CCXML and SIP Incoming Header Access

The specification for CCXML defines some protocol-independent connection-related variables that can be used to return related connection data. Blueworx Voice Response for Linux Version 7 supports these session variables. The settings for the protocol independent connection variables defined by CCXML are as follows:

Table 1. CCXML protocol independent connection variables
Connection Variable Value
event$.connection.aai The setting of the value associated with the aai or uui keyword in the incoming REQ_HDR (see below for a full explanation)
event$.protocol SIP
event$.connection.protocol.version 0

The settings for the generic protocol specific variables defined by CCXML are as follows:

Table 2. CCXML generic protocol specific variables
Variable Value
event$.connection.protocol.sip.protocol.value "sip"
event$.connection.protocol.sip.protocol.variant RFC3261
event$.connection.protocol.sip.protocol.num 24, 36, or other valid number (depending on the value of the NUM attribute of the PROTOCOL call tag).

All protocol specific call tags and attributes supported by Blueworx Voice Response are also available as independent CCXML variables (in lower case), if the tag data is present in the call. Tags are returned as a key where the key is the tag name. To read a tag value use key.value, to read an attribute use key.attribute_name. All key and attribute_names are in lower case. The tag and attribute values returned have their case preserved.

Using call information in CCXML

In SIP, the TO_HDR tag contains header data. The corresponding CCXML variables are:

event$.connection.protocol.sip.to_hdr
event$.connection.protocol.sip.to_hdr.value

To check if this variable is currently in use, you can use the approach in the following CCXML code snippet:

<if cond="event$.connection.protocol.sip.to_hdr != undefined">
   <log expr="'connection.alerting connection.protocol.sip.to_hdr.value: '
          + event$.connection.protocol.sip.to_hdr.value"/>
<else/>
   <log expr="'connection.alerting connection.protocol.sip.to_hdr: undefined'"/>
</if>

Using the SIP REQ_HDR call tag information in CCXML is more complicated because any key value pairs after the first terminator (";" or "&") on the REQ_HDR call tag are returned as variables. For example, the following REQ_HDR:

<'REQ_HDR'='sip:1234@siphost.blueworx.com;uui=uui1;aai=aai1;voicexml=Weather.vxml;
            maxage=3600;maxstale=0'>

resolves to the following independent CCXML event$.* variables shown in the following CCXML example:

<log expr="'connection.alerting connection.protocol.sip.req_hdr.value: '
          + event$.connection.protocol.sip.req_hdr.value"/>
<log expr="'connection.alerting connection.protocol.sip.req_hdr.aai: '
          + event$.connection.protocol.sip.req_hdr.aai"/>
<log expr="'connection.alerting connection.protocol.sip.req_hdr.uui: '
          + event$.connection.protocol.sip.req_hdr.uui"/>
<log expr="'connection.alerting connection.protocol.sip.req_hdr.voicexml: '
          + event$.connection.protocol.sip.req_hdr.voicexml"/>
<log expr="'connection.alerting connection.protocol.sip.req_hdr.maxage: '
          + event$.connection.protocol.sip.req_hdr.maxage"/>
<log expr="'connection.alerting connection.protocol.sip.req_hdr.maxstale: '
          + event$.connection.protocol.sip.req_hdr.maxstale"/> 

The last key of aai in the REQ_HDR tag is also mapped into the event$.connection.aai session variable. If no aai keys are present, the last uui key is mapped. If no aai or uui keys are present, the event$.connection.aai session variable is empty.

Note: The Blueworx Voice Response SIP stack:
Figure 1 is an example CCXML file that shows how SIP REQ_HDR call tags can be used to select a VoiceXML file to process and how call tags can be passed as parameters to the VoiceXML application. The following REQ_HDR would cause the logparameters.vxml file to be processed:
<'REQ_HDR'='sip:1001@9.20.49.176:5060;voicexml=logparameters.vxml;filename=myfile;filetype=wav'>
The following REQ_HDR would cause a fetch for start.jsp
<'REQ_HDR'='sip:1001@9.20.49.176:5060;jsp=start.jsp;filename=myfile;filetype=wav'>

The CCXML file also shows how a fetch request for a VoiceXML document (generated by a JSP) with attached parameters can be created based on SIP REQ_HDR call tags from an incoming SIP call.

<?xml version="1.0"?>
<ccxml version="1.0">

<!--                                                                              -->
<!-- A simple CCXML example that looks for parameters provided on the SIP REQ_HDR -->
<!-- and uses them to start a vxml application on the local file system           -->
<!-- or post to a http server specifying the jsp                                  -->
<!-- So if a jsp of "start.jsp" is supplied with filename = "myfile"              -->
<!-- and filetype = "wav"                                                         -->
<!-- then the following fetch request will be sent:                               -->
<!-- http://server1.test.org/myapplication/start.jsp?filetype=wav&filename=myfile -->
<!--                                                                              -->

  <eventprocessor>

    <transition event="ccxml.loaded">
      <log expr="'[' + event$.name + '] Loaded CCXML application to invoke Dynamic VXML '"/>
    </transition>

    <transition event="connection.alerting">
      <log expr="'[' + event$.name + '] Ringing...'"/>
      <accept/>
    </transition>

    <transition event="connection.connected">
      <log expr="'[' + event$.name + '] Answered'"/>
      <!-- check ??? -->
        <if cond="event$.connection.protocol != null">
        <!-- see if SIP call -->
          <if cond="event$.connection.protocol.sip != null">

          <!-- see if voicexml tag provided -->
            <if cond="event$.connection.protocol.sip.req_hdr.voicexml != null">
              <!-- hard code where to find vxml files -->
              <var name="vxmlname" expr="'file:///home/dtuser/'"/>

              <assign name="vxmlname" expr="vxmlname + event$.connection.protocol.sip.req_hdr.voicexml"/>
                <log expr="'[' + event$.name + '] Starting file = ' + vxmlname"/>

                <!-- see if filename tag provided on REQ_HDR -->
                <if cond="event$.connection.protocol.sip.req_hdr.filename != null">
                  <var name="filename" expr="event$.connection.protocol.sip.req_hdr.filename"/>
                    <log expr="'[' + event$.name + '] Passing filename = ' + filename"/>

                    <!-- see if filetype tag provided on REQ_HDR -->
                      <if cond="event$.connection.protocol.sip.req_hdr.filetype != null">
                        <var name="filetype" expr="event$.connection.protocol.sip.req_hdr.filetype"/>
                          <log expr="'[' + event$.name + '] Passing filetype = ' + filetype"/>
                           <!-- start VXML application with both parameters -->
                        <dialogstart src="vxmlname"  parameters="filename filetype"/>
                      <else/>
                        <!-- start VXML application with filename parameter -->
                        <dialogstart src="vxmlname"  parameters="filename"/>
                      </if>
                        <else/>
                            <!-- start VXML application with no parameters -->
                            <dialogstart src="vxmlname"/>
                        </if>
Figure 1. CCXML file using parameters derived from SIP REQ_HDR call tags
          <!-- see if jsp tag provided -->
            <elseif cond="event$.connection.protocol.sip.req_hdr.jsp != null"/>
              <!-- hard code where to find jsp on server -->
              <var name="jspname" expr="'http://server1.test.org/myapplication/'"/>

              <assign name="jspname" expr="jspname + event$.connection.protocol.sip.req_hdr.jsp"/>
                <log expr="'[' + event$.name + '] File from server = ' + jspname"/>

              <!-- see if filename tag provided on REQ_HDR -->
              <if cond="event$.connection.protocol.sip.req_hdr.filename != null">
                <var name="filename" expr="event$.connection.protocol.sip.req_hdr.filename"/>
                  <log expr="'[' + event$.name + '] Passing filename = ' + filename"/>

                <!-- see if filetype tag provided on REQ_HDR -->
                <if cond="event$.connection.protocol.sip.req_hdr.filetype != null">
                  <var name="filetype" expr="event$.connection.protocol.sip.req_hdr.filetype"/>
                  <log expr="'[' + event$.name + '] Passing filetype = ' + filetype"/>
                  <!-- fetch from server with both parameters, "http:" in jspname causes a fetch -->
                  <dialogstart src="jspname"  namelist="filename filetype"/>
                <else/>
                <!-- fetch from server with filename parameter, "http:" in jspname causes a fetch -->
                  <dialogstart src="jspname"  namelist="filename"/>
                </if>
           <else/>
             <!-- fetch from server with no parameters, "http:" in jspname causes a fetch -->
             <dialogstart src="jspname"/>
           </if>
         <else/>
           <log expr="'[' + event$.name + '] No VXML or JSP application supplied, hanging up'"/>
           <disconnect connectionid="event$.connectionid"/>
         </if>
       <else/>
         <log expr="'[' + event$.name + '] Was not a SIP call, hanging up'"/>
         <disconnect connectionid="event$.connectionid"/>
       </if>
     <else/>
       <log expr="'[' + event$.name + '] Did not have connection information available, hanging up'"/>
       <disconnect connectionid="event$.connectionid"/>
     </if>
   </transition>

   <transition event="dialog.started">
     <log expr="'[' + event$.name + ']'"/>
   </transition>

    <transition event="dialog.exit">
      <log expr="'[' + event$.name + '] Hanging up'"/>
      <disconnect connectionid="event$.connectionid"/>
    </transition>

    <transition event="connection.disconnected">
      <log expr="'[' + event$.name + '] Disconnected...'"/>
    </transition>

    <transition event="error.*">
      <log expr="'[' + event$.name + '] - reason was ' + event$.reason"/>
    </transition>

    <transition event="*">
      <log expr="'[' + event$.name + '] occured unexpectedly, not doing anything.'"/>
    </transition>

  </eventprocessor>
</ccxml>

Using SIP CALLID_HDR and CALLINFO_HDR tags

For an incoming call, the SIP CALLID_HDR and CALLINFO_HDR can be used in a similar way.

To access CALLID_HDR and CALLINFO_HDR in CCXML, use the connection variables shown in the following table:

Table 3. Accessing SIP CALLID_HDR and CALLINFO_HDR headers
Variable Content
event$.connection.protocol.sip.callid_hdr.value Call-ID
event$.connection.protocol.sip.callinfo_hdr.value Full Call-Info
event$.connection.protocol.sip.callinfo_hdr.count The number of Call-Info headers present
event$.connection.protocol.sip.callinfo_hdr.infoN.uri The URI for Call-InfoN
event$.connection.protocol.sip.callinfo_hdr.infoN.purpose The purpose for Call-InfoN (if present in the header)
event$.connection.protocol.sip.callinfo_hdr.infoN.infoparam The infoparam for Call-InfoN (if present in the header), where infoparam is the name of an information parameter present in the information, for example, icon or card.
In this example, the source Call-Info header contains the following:
<http://www.code.com/my-picture.jpg>;purpose=icon
<http://www.example.oom/alice/>;purpose=info
<http://www.google.com>;purpose=info;username=access;single
event$.connection.protocol.sip.callinfo_hdr.value:
	<http://www.code.com/my-picture.jpg>;purpose=icon,
	<http://www.example.oom/alice/>;purpose=info,
	<http://www.google.com>;purpose=info;username=access;single=
event$.connection.protocol.sip.callinfo_hdr.count: 3
event$.connection.protocol.sip.callinfo_hdr.info1.uri: http://www.code.com/my-picture.jpg
event$.connection.protocol.sip.callinfo_hdr.info1.purpose: icon
event$.connection.protocol.sip.callinfo_hdr.info2.uri: http://www.example.oom/alice/
event$.connection.protocol.sip.callinfo_hdr.info2.purpose: info
event$.connection.protocol.sip.callinfo_hdr.info3.uri: http://www.google.com
event$.connection.protocol.sip.callinfo_hdr.info3.purpose: info
event$.connection.protocol.sip.callinfo_hdr.info3.username: access
event$.connection.protocol.sip.callinfo_hdr.info3.single:

Using other SIP header tags

For an incoming call, other, non-standard SIP header tags can be used in a similar way.

To access other SIP header information in CCXML, use the connection variables as in the following generic example:

<if cond="event$.connection.protocol.sip.header name != undefined">
 <log expr="'[connection.alerting] connection.protocol.sip.header name.value:
            ' + event$.connection.protocol.sip.header name.value"/>
<else/>
 <log expr="'[connection.alerting] connection.protocol.sip.header name: undefined'"/>
</if>

Examples

A SIP header with the name supported:

<if cond="event$.connection.protocol.sip.supported != undefined">
 <log expr="'[connection.alerting] connection.protocol.sip.supported.value:
            ' + event$.connection.protocol.sip.supported.value"/>
<else/>
 <log expr="'[connection.alerting] connection.protocol.sip.supported: undefined'"/>
</if>

A SIP header with a name that includes a special character, such as ‘-’, user-to-user:

<if cond="event$.connection.protocol.sip['user-to-user'] != undefined">
 <log expr="'[connection.alerting] connection.protocol.sip['user-to-user'].value:
            ' + event$.connection.protocol.sip['user-to-user'].value"/>
<else/>
 <log expr="'[connection.alerting] connection.protocol.sip['user-to-user']: undefined'"/>
</if>