W3C

Voice Browser Call Control: CCXML Version 1.0

W3C Working Draft 11 October 2002

This version:
http://www.w3.org/TR/2002/WD-ccxml-20021011/
Latest version:
http://www.w3.org/TR/ccxml/
Previous version:
http://www.w3.org/TR/2002/WD-ccxml-20020221/
Editor:
RJ Auburn, Voxeo <rj@voxeo.com>
Contributors:
David Attwater, BTexact Technologies <david.attwater@bt.com>
Eric Burger, Snowshore <eburger@snowshore.com>
Ken Davies, Hey Anita <Kend@heyanita.com>
Rajiv Dharmadhikari, Telera <rajiv@telera.com>
Dave Donnelly, BTexact Technologies <dave.donnelly@bt.com>
Daniel Evans, Nortel Networks <dde@nortelnetworks.com>
Mike Galpin, Syntellect <mgalpin@syntellect.com>
Markus Hahn, Voxeo <markus@voxeo.com>
Gadi Inon, Comverse <gad.inon@comverse.com>
Rob Marchand, VoiceGenie <rob@voicegenie.com>
Paolo Baggia, Loquendo <Paolo.Baggia@loquendo.com>
Brad Porter, TellMe Networks <brad@tellme.com>
Kenneth Rehor <ken@rehor.com>
Saravanan Shanmugham, Cisco <sarvi@cisco.com>
Jim Trethewey, Intel <jim.r.trethewey@intel.com>
Wai-Yip Tung, Cisco <wtung@cisco.com>

Abstract

This document describes CCXML, or the Call Control eXtensible Markup Language. CCXML is designed to provide telephony call control support for VoiceXML or other dialog systems. CCXML has been designed to complement and integrate with a VoiceXML system. Because of this you will find many references to VoiceXML's capabilities and limitations. You will also find details on how VoiceXML and CCXML can be integrated. However it should be noted that the two languages are separate and are not required in an implementation of either language. For example CCXML could be integrated with a more traditional IVR system and VoiceXML or other dialog systems could be integrated with some other call control systems.

Status of this Document

This specification describes markup for designed to provide telephony call control support for VoiceXML or other dialog systems. CCXML is far from complete. This draft is meant to give people access to an early version of the language so that people can understand the direction that the working group is moving in. This document has been produced as part of the W3C Voice Browser Activity, following the procedures set out for the W3C Process . The authors of this document are members of the Voice Browser Working Group ( W3C Members only ). This is a Royalty Free Working Group, as described in W3C's Current Patent Practice note. Working Group participants are required to provide patent disclosures.

This document is for public review, and comments and discussion are welcomed on the public mailing list <www-voice@w3.org>. To subscribe, send an email to <www-voice-request@w3. org> with the word subscribe in the subject line (include the word unsubscribe if you want to unsubscribe). The archive for the list is accessible online.

This is a W3C Working Draft for review by W3C Members and other interested parties. It is a draft document and may be updated, replaced or made obsolete by other documents at any time. It is inappropriate to use W3C Working Drafts as reference material or to cite them as other than "work in progress".

This is work in progress and does not imply endorsement by the W3C membership. A list of current W3C Recommendations and other technical documents, including Working Drafts and Notes, can be found at http://www.w3.org/TR/ .

Table of Contents

Section 1: Introduction

This document describes CCXML, or Call Control eXtensible Markup Language. CCXML is designed to provide telephony call control support for VoiceXML or other dialog systems. CCXML is intended to be an adjunct language to be used with a VoiceXML or other dialog implementation platform.

CCXML has been designed to complement and integrate with a VoiceXML system. Because of this you will find many references to VoiceXML's capabilities and limitations. You will also find details on how VoiceXML and CCXML can be integrated. However it should be noted that the two languages are separate and are not required in an implementation of either language. For example CCXML could be integrated with a more traditional IVR system and VoiceXML or other dialog systems could be integrated with some other call control systems.

CCXML is far from complete. This draft is meant to give people access to an early version of the language so that people can understand the direction that the working group is moving in.

Please note that this is a large document, and there are lots of improvements to make to it. However, it's more important to get widespread discussion on CCXML's ideas than to spend eternity refining it. There are a number of known issues and improvements, which are listed in this document in green. . It holds ideas that should be incorporated, but were not included in this draft because of time constraints.

Section 2: Background

This section outlines some of the capabilities required to support the scenarios described in the Introduction, and then describes the architectural model needed to make them easy to manipulate. There are a number of needed features that VoiceXML currently can't supply:

We originally intended to see if we could add new tags to VoiceXML to support the new features here. However, we repeatedly encountered conflicts between the design goals for VoiceXML, and the requirements we list here.

Most of these conflicts came from trying to reconcile two very different event models. Event generation and handling in VoiceXML are focused on specific user interface transactions (e.g., within a given field, the filled, noinput, nomatch, or help events are thrown and handled). However, events from telephony networks or external networked entities are non-transactional in nature; they can occur at any time, regardless of the current state of VoiceXML interpretation. These events could demand immediate attention. We could either abandon VoiceXML's admirably simple single-threaded programming model, or delay event-servicing until the VoiceXML program explicitly asked to handle such events. Instead of making either of these bad choices, we instead move all call control functions out of VoiceXML into an accompanying CCXML program. VoiceXML can thus focus on being effective for voice dialogs, while CCXML tackles the very different problems we described above.

An implementation of VoiceXML is not required to support CCXML. Such implementations may choose to support proprietary methods of call control, and still be deemed compliant with the W3C VoiceXML Recommendation.

An implementation of CCXML is not required to support VoiceXML. Such implementations may choose not to support interactive dialogs at all, or may do it in a proprietary way, and still be deemed compliant with the W3C CCXML Recommendation.

A complete telephony service application can be comprised of web server CGI-compliant application logic, one or a sequence of CCXML scripts to perform call control actions, and one or a sequence of dialogs to perform user media interactions

Section 3: Concepts

Properly adding advanced telephony features to VoiceXML entails adding not just a new telephone model, but new call management and event processing, as well. We'll briefly cover these three areas here. Since new event processing has the largest impact on our architecture, let's examine it first.

Section 3.1: Event Processing

Telephone applications need to receive and process large numbers of events. These events arrive from outside the program itself - either the underlying telephony platform, or from other programs. They must be processed quickly, as any delays could be discerned by the user.

Unfortunately, VoiceXML is not designed for the task. Its event model assumes only "synchronous" events - those which occur only when the program occupies certain states. (For example, a nomatch event can only occur within a field.) The language would have to be augmented to properly handle events which can arrive at any time. (It's true that telephone.disconnect can occur at any time, but this is something of a special case.) Further, it would be tough to reconcile the need for immediate processing with VoiceXML's single-threaded model.

Instead, we move all asynchronous handling to a CCXML program. Every executing VoiceXML program has an associated CCXML program. It runs on a thread separate from the VoiceXML dialog. When an event is delivered to a user's voice session (now a coupling of an active VoiceXML dialog and its CCXML program), it is appended to the CCXML program's queue of events. The CCXML program spends almost all its time removing the event at the queue's head, processing the event, and then removing the next event. Meanwhile, the VoiceXML dialog can interact with the user, undisturbed by the incoming flow. Most VoiceXML programs never need to consider event processing at all.

Writing a CCXML program, then, mainly involves writing the handlers which are executed when certain events arrive. There are mechanisms for passing information back and forth between VoiceXML and CCXML, but the important points are that CCXML:

Note: References to threads are meant as logical threads and do not imply any specific platform implementation.

Section 3.2: Conferencing

VoiceXML currently has very few options for conferencing. Only the transfer tag will establish any kind of connection between two voice callers; calls involving more than two parties, or other advanced applications, are out of reach. VoiceXML is largely a language for voice dialogs, and is silent on many telephony issues.

We would like a far more powerful and flexible method of creating calls. To do so, we introduce a few ideas here:

Section 3.3: Call Management

VoiceXML also fails to offer sufficient control over the underlying telephone network. Although VoiceXML offers the disconnect directive to hang up an existing phone call, there are a number of desirable features to which the VoiceXML programmer cannot get access. They include:

We want to expose the phone network in a provider-neutral way, while still offering enough methods and information to be interesting. Toward that end, we have taken the Java Soft JCP call model for telephony-access. The topic is discussed below in more depth.

Section 3.4: Scripting

Section 3.4.1 Introduction

The computational semantics of CCXML are based on the ECMAScript Compact Profile (ES-CP, also known as ECMA-327). Execution efficiency is a goal of the designers of CCXML, and ES-CP was chosen in order to avoid excessive execution overhead.

The ES-CP document states,

'ECMAScript Compact Profile is a subset of ECMAScript 3rd Edition tailored to resource-constrained devices such as battery powered embedded devices. Therefore, special attention is paid to constraining ECMAScript features that require proportionately large amounts of system memory (both for storing and executing the ECMAScript language features) and continuous or proportionately large amounts of processing power.'

CCXML is not intended for battery powered embedded devices, but it is intended to be practical for large, real-time telephony platforms managing thousands of lines. The constraints of ES-CP emphasize CCXML's ongoing concern for execution efficiency.

Even though ES-CP tends to be implemented using interpreters, CCXML does not require an interpretive implementation. ES-CP can be compiled to a target language such as C, and thus in turn to machine code, so that CCXML documents which are static can be rendered once in machine code. Even frequently modified CCXML documents can be translated and compiled on their way from the document server to the CCXML execution environment, in order to avoid multiplying interpretive overhead by the number of lines that execute the document.

The emphasis on efficiency in CCXML is also shown by the avoidance of features which can only be implemented either by interpretation or run-time evaluation.

The choice of an implementation strategy is up to the CCXML implementer. CCXML is designed to allow a range of choices in order to accommodate practical implementations on a wide variety of platforms.

Section 3.4.2 Definitions

The following terms, which are used throughout this specification, are defined here.

ECMAScript left-hand-side expression - defined in ECMA-262 11.2; this is an expression which produces a result to which a value can be assigned; an expression which is valid as the left hand operand of an assignment (=) operator;

ECMAScript expression - defined in ECMA-262 11.14; this is an expression which produces a value; an expression which is valid on the right hand side of an assignment operator;

ECMAScript variable name - defined in ECMA-262 7.6; this is any valid sequence of characters, known as an identifier, which can be used as a variable name, a property name, or a function name; this does not include any qualifiers, such as array or property accessors;

Empty ECMAScript object - an object returned by the new Object() expression; an object with no properties.

CCXML variable name - a variable name declared in a CCXML <var> element, with optional dot separated qualification.

Scope element - a CCXML element which defines a variable scope; <ccxml> and <transition> are CCXML scope elements.

Section 4: Object Model and Programming Contract

There are several identifiable objects in the CCXML universe, all of which have a globally unique identifier, probably in the form of a URI.

There also exist voice dialogs, which do not need to be globally-uniquely identified. Whenever active, they must interact with a two-way audio stream. Today, this audio always comes from a call leg. In the future, it might also come from a conference object.

CCXML can manipulate the language objects through tags defined in the CCXML language. It sometimes can also send and/or receive the asynchronous events (mentioned above) with these objects.

diagram showing call legs & voice dialogs

CCXML directly touches call legs, conferences, and audio connections with various tags in the language, such as accept , createconference , and join . CCXML may also receive events from all three, in the case of line signaling, line-status informational messages, or error and failure scenarios. Call legs, conferences, and audio connections do not accept events; CCXML must use the builtin tags to direct them.

CCXML can start and kill voice dialogs using language tags. It can receive events from voice dialogs, which may be standardized events such as dialog.exit , or application-specific ones. It would also be very handy for CCXML to be able to send an event to a voice dialog. We describe below how VoiceXML might be slightly modified to synchronously process arbitrary external events, much as it processes recognition events today. CCXML's only guaranteed control over a dialog is start and kill. Even if VoiceXML will process these external events, anything more than lifetime-management must be specifically supported by the voice dialog.

Finally, CCXML can create other CCXML programs using a language tag. That is the only guaranteed control one CCXML program ever wields over another. Any other interaction takes place through the event mechanism. CCXML programs can both send and receive events between one another.

Section 5: CCXML Elements Listing

<accept> Accept an incoming phone call
<authenticate> Authenticate a ccxml script
<assign> Assign a variable a value
<ccxml> Start a CCXML program
<createcall> Make an outbound call
<createccxml> Create a new CCXML program
<createconference> Create a multi-party audio conference
<destroyconference> Destroy a multi-party audio conference
<dialogstart> Start a dialog program's execution
<dialogterminate> Stop a dialog program's execution
<disconnect> Terminate a phone connection
<else> Used in <if> statements
<elseif> Used in <if> statements
<eventhandler> Block of event-processing statements
<exit> Ends execution of the CCXML program
<fetch> Pre-load a CCXML file
<goto> Move execution to a new location
<if> Conditional logic
<join> Connect two audio sources
<move> Move a event to another ccxml session
<redirect> Redirect an incoming call to a new endpoint
<reject> Reject an incoming phone call
<script> Run ECMA Script
<send> Generate an event
<transition> A single event-processor block
<unjoin> Disconnect two audio sources
<var> Declare a variable

 

Section 6: Document Control Flow and Execution

Section 6.1: Overview

The execution of a CCXML document begins with the ccxml tag at the top and then proceeds tag by tag in document order. The flow of the execution can be changed with the help of if , elseif , else , fetch , and goto tags. Most of a CCXML program's execution will take place within an eventhandler , which processes a stream of incoming events. As with VoiceXML applications, a CCXML application can consist of multiple CCXML documents, traversed by use of goto and fetch .

Section 6.2: Tags

Here are the details of the CCXML tags for control flow and execution.

Section 6.2.1: <ccxml>

Section 6.2.1.1: Overview

This is the parent tag of a CCXML document and encloses the entire CCXML script in a document. When a <ccxml> element is executed, its child elements are collected logically together at the beginning of the document and executed in document order before the target <eventhandler>. This is called document initialization.

Section 6.2.1.2: CCXML Attribute Details
Attribute Name Details
version The version of this CCXML document (required). The initial version number is 1.0.

Section 6.2.2: <if>

Section 6.2.2.1: Overview

The if tag works just as it does inside VoiceXML. It is a straightforward program-control element. The else and elseif elements can appear optionally within an if element.

Section 6.2.2.2: If Attribute Details
Attribute Name Details
cond An ECMAScript expression which can be evaluated to true or false.

Section 6.2.3: <elseif>

Section 6.2.3.1: Overview

The elseif tag works just as it does inside VoiceXML. It is a straightforward program-control element. The else and elseif elements can appear optionally within an if element.

Section 6.2.3.2: Elseif Attribute Details
Attribute Name Details
cond An ECMAScript expression which can be evaluated to true or false.

Section 6.2.4: <else>

Section 6.2.4.1: Overview

The else tag works just as it does inside VoiceXML. It is a straightforward program-control element. The else and elseif elements can appear optionally within an if element.

Section 6.2.4.2: Else Attribute Details
Attribute Name Details
none none

Section 6.2.5: <fetch> and <goto>

Section 6.2.5.1: Overview

The fetch tag, together with goto , is used to transfer execution to a different CCXML document in a multi-document CCXML application. In VoiceXML this is performed via the goto tag, which blocks execution until the target page is loaded and ready to execute. CCXML programs, however, can be substantially more timing-sensitive than VoiceXML ones. All event-handling would have to be suspended until a blocking goto had found the target page, loaded, and parsed it. The time required could be hundreds of milliseconds or seconds, periods too lengthy for ignoring important incoming events.

Instead, we break the functions of VoiceXML's goto command into two parts. The fetch operator tells the interpreter to find, load, and parse a given page of CCXML. Execution returns from the tag immediately, and the CCXML interpreter can continue on while the execution context works to get the target document ready for execution. When the fetch completes, the document which issued the fetch receives a fetch completion event. It can then issue a goto to immediately start executing the now-fetched page.

Below is a small snippet of code from the CCXML program's event handler. We execute a fetch operation, and continue on to assign to a state variable, and maybe handle more events. Eventually, the fetch completes, the CCXML interpreter services the event, and we perform the goto .

<fetch next="http://www.web.com/control.ccxml"/>
<--control continues here->
<assign name="state_var" expr="fetch_wait"/>
</transition>

<!-- ……… -->

<transition state="fetch_wait" event="fetch.done" name="evt"/>
<goto fetchid="evt.fetchid"/>
</transition>

There's no requirement to goto previously-fetched pages, but it is wasteful to not do so.

Section 6.2.5.2: Fetch Attribute Details
Attribute Name Details
next an ECMAScript expression which returns the URI of the CCXML document  to be fetched.
namelist a list of zero or more CCXML variable names. These variable names and  their associated values will be included in the URI sent to the server.
method indicates the HTTP method to use. Valid values are "get" and "post". The default is "get".
fetchid is an ECMAScript left-hand-side expression which receives an internally generated unique string identifier to be associated with the completion event. This identifier can be tested by the fetch completion event handler to distinguish among several outstanding fetch requests.  If this attribute is not specified, the fetch ID can be acquired from the fetch completion event.  Every fetch request will receive a unique fetch ID, even requests for the same document.
synch is an ECMAScript left-hand-side expression that is set to the fetch completion event. The specification of this attribute in a fetch element implies a blocking fetch, which will be executed synchronously.  If this attribute is not specified, the fetch is asynchronous.

Asynchronous execution of a fetch element initiates a request for the CCXML document identified by its attributes.  Execution immediately continues with the element following the fetch.  When the asynchronous request has completed, the fetch completion event will be generated.  If the fetch fails for any reason, a fetch fail event will be generated instead.

When fetch is executed synchronously, the CCXML document blocks until the fetch completes, and the fetch completion event is stored as identified by the synch attribute. In this case, the element following the fetch element will not be executed until fetch completes. The properties of the fetch completion event can be tested to determine the result of the fetch request, so that error handling alternatives can be provided.

Section 6.2.5.3: Goto Attribute Details
Attribute Name Details
fetchid an ECMAScript expression which returns the fetch ID of a document referenced in a fetch completion event.  The fetch ID can be acquired in a <fetch> with the fetchid attribute.  The fetch completion event also provides a property whose value is the fetch ID of the document fetched.

A goto element transfers control to the document identified by the fetch ID.  The execution of a goto element does not depend upon whether the target document was fetched synchronously or asynchronously.  However, the fetch completion event must have arrived before the <goto> is executed, otherwise, an error event is generated.

When a goto element is executed, the target document replaces the current document in its thread of control.  Event endpoints associated with this thread of control are inherited by the target document.  Execution of the current document terminates.

Issue Note:

After a document has been fetched, it is eligible for execution.  How long it remains eligible is an outstanding question.  A document's fetch ID is known potentially by the document that issued the <fetch>, and the document that received the fetch completion event.  Once these documents have terminated, the fetched document may no longer be accessible.

Section 6.2.6: <Createccxml>

Section 6.2.6.1: Overview

The createccxml tag is used to create another CCXML  thread of control , which begins execution with the document identified by this element. The term "thread of control" is not meant to imply a particular form of implementation. A CCXML thread of control exists for each concurrently executing CCXML document. A thread of control provides independent execution and a separate variable space for the CCXML documents it executes. A thread of control is associated with one or more event endpoints and will receive events only from those endpoints. The execution of a CCXML document may add or subtract event endpoints from a thread of control.

The createccxml tag is used to create another CCXML program instance. The new CCXML program has no relation to its creator once spawned, and has a wholly separate lifetime and address space.

Section 6.2.6.2 Createccxml Attribute Details
Attribute Name Details
fetchid an ECMAScript expression which returns the fetch ID of a document referenced in a fetch completion event.  This is the ID of the document that will begin execution in the new thread of control.  The fetch ID can be acquired in a <fetch> with the fetchid attribute.  The fetch completion event also provides a property whose value is the fetch ID of the document fetched.
start an ECMAScript expression which returns an event object which is the initial event for the new thread of control. This event will be the first event sent to the document started by this element. The endpoint which originated this event will be inherited by the new thread of control. This attribute is optional.
sessionid an ECMAScript left-hand-side expression that is set to an internally generated unique string identifier which identifies the newly created thread of control. This attribute is optional.
Issue:

When a new thread of control is created by <createccxml>, can the creating document handle events which are not processed by the new CCXML document?  <createccxml> implies a creation hierarchy with parent creators of child threads of control.  Although a document may choose to ignore an event, it may not be good for all documents to ignore the event.  If the parent document can optionally express an interest in events which are not processed by its children, unprocessed events can propagate up the hierarchy to possibly be handled by a document which is interested.  At the very top level, a "*.*" event handler may choose to write unprocessed events to an alarm log so nothing goes unprocessed.  This upward event propagation is similar to other popular event processing models.

Section 6.2.7: <exit>

Section 6.2.7.1: Overview

The exit tag ends execution of the CCXML program. All pending events are discarded, and there is no way to restart CCXML execution.

The exit tag ends execution of a CCXML document and its thread of control.

Section 6.2.7.2 Exit Attribute Details
Attribute Name Details
expr A return ECMAScript expression (e.g. 0 or 'oops!'). This attribute is optional; if omitted, a value of zero is assumed.  This value is stored as a property of the exit event.
namelist a list of zero or more CCXML variable names to be returned which will be set as properties of the exit event.

A CCXML script executing the <exit> tag will generate a ccxml.exit event to the parent document/thread of control. The exiting document will be identified on the exit event by its session ID.

Issue:

Where does the exit event get delivered?  The exit event could be propagated up the <createccxml> hierarchy until it is processed by a document <transition> element.  If the exit event is not processed, it would be dropped.

Issue:

What happens to the event sources which were previously associated with the exiting document?  A document which processes an exit event could implicitly assume ownership of the event endpoints owned by the exiting document, and therefore would receive any events subsequently originating from these endpoints.

Issue:

What happens to events queued for the exiting document?

Section 6.3: Events

Section 6.3.1: Overview

CCXML uses several threads to deal with document fetching, startup and shutdown.

The following are the CCXML events that have to do with this:

Section 6.3.2: fetch.done - Fetch Completion Event

This event is generated when a fetch request completes. It is delivered to the document which issued the request.

The fields of this event are:

Field Name Details
name fetch.done
fetchid The internally generated unique fetch identifier
uri The URI of the fetch request.

Section 6.3.3: error.fetch - Fetch Error Event

This event is generated when a fetch request does not successfully complete. It is delivered to the document which issued the request.

The fields of this event are:

Field Name Details
name error.fetch
fetchid The internally generated unique fetch identifier
error A string description of the fetch error.
uri The URI of the fetch request.

Section 6.3.4: ccxml.exit - CCXML Document Exit Event

This event is generated when a CCXML document executes an <exit> element.

The fields of this event are:

Field Name Details
name ccxml.exit
sessionid the identifer of the exiting thread of control; this is the same value returned to the sessionid attribute of the <createccxml> which created this thread of control;
expr the value of the <exit> expr attribute;
namelist If the namelist attribute was specified in the <exit>, this property is a string valued array of the names in the list.  The length of the property is equal to the number of names in the list. The actual values are stored in the "values" sub-object.
values.* Each name in the namelist is a property whose value is the value of the name at the time the <exit> was executed.

Section 6.3.5: ccxml.loaded - CCXML Document Loaded Event

This event is generated for a newly loaded CCXML document to provide an opportunity for initialization.

The fields of this event are:

Field Name Details
name ccxml.loaded
sessionid the identifier of the thread of control on which this document is executing;

Section 7: Dialogs

Section 7.1: Overview

CCXML deals with all user interaction as "dialogs". Any time you want to perform an action where you interact with a caller you start a dialog on their session. Once a dialog has completed it can then return back to the CCXML program and the CCXML program can then make a decision on what to do next depending on what was returned.

Dialogs are not tied to any single dialog language. The requirements on a dialog language are very small and this could be implemented on anything from VoiceXML, SALT and even Traditional IVR languages and platforms. Because of this a CCXML platform may support interaction with several dialog systems based on the mime type passed in at dialog startup.

CCXML treats starting a dialog as an asynchronous action meaning that when you start the dialog the control returns immediately back to the CCXML program and the CCXML program is notified of the result by an asynchronous event.

Section 7.2: Tags

Section 7.2.1: <dialogstart>

Section 7.2.1.1: Overview

The <dialogstart> tag is used to launch a dialog and associate it with an indicated call leg. The tag includes a URL reference to a start-document for a dialog manager. The launched dialog executes on a separate thread of execution (may be a thread, process, or system depending upon platform implementation), not on CCXML's thread of execution. Once the dialog is kicked off, the CCXML script can immediately go back to handling incoming events.

The <dialogstart> tag does not block execution of the CCXML script until the started dialog completes. The CCXML script regains control immediately. If the dialog cannot be started for any reason, an error.dialog.notstarted error event is thrown.

When the dialog completes, a "dialog.exit" event is posted to the event queue of the CCXML instance that launched it.

When the dialog is started if the dialog language allows access to telephony variables such as ANI, DNIS and UUI this will be propagated from the call leg to the dialog application.

Section 7.2.1.2: dialogstart Attribute Details
Attribute Name Details
callid Is an ECMAScript expression which returns a call leg object to associate the new dialog with. The default value of the "callid" attribute is "_event.source", meaning that the dialog instance will be launched for whatever call object generated the previous event (typically a connection.CONNECTION_CONNECTED event).
src Is an ECMAScript expression which returns a character string identifying the URL of the dialog document that the dialog interpreter should load and begin executing upon startup.
type Specifies the MIME type of the document, and as a result, which dialog interpreter is actually loaded. A MIME type of "application/xml+vxml" associates the start-document with a VoiceXML interpreter instance. A MIME type of "audio/wav" associates the start-document with a dialog manager that merely plays wave files. If omitted, the mime-type attribute defaults to "application/xml+vxml", but the CCXML interpreter is free to guess the correct MIME type, e.g., by examining the filename-extension of the start-doc URL.
namelist Specifies the list of ECMA script variables that should be appended to the dialog url as parameters. This is useful where you need to create the url based on previous actions in the script.
dialogid an ECMAScript left-hand-side expression that will receive the value of the session-name identifying the launched dialog interpreter instance. This session-name can be used by the CCXML script programmer in future invocations of <dialogterminate>.

Section 7.2.2: <dialogterminate>

Section 7.2.2.1: Overview

A CCXML script may decide that it wants to destroy a current dialog. This is accomplished using the <dialogterminate> tag in a CCXML script.

When the CCXML interpreter encounters a <dialogterminate> tag, it sends a terminate event to the specified dialog.

Note that a dialogterminate request cannot be honored if the launched dialog is not yet in a ready state to receive it and act upon it. If this happens, a "error.dialog.wrongstate" event will be thrown.

When the CCXML application does a <dialogterminate> the dialog will still have a chance to return data to the CCXML application using a dialog.exit event. The details of how this mapping is done is up to the dialog language.

If you set the immediate attribute to true however the dialog does not get a chance to return data to the CCXML application and the CCXML application receives the dialog.exit event right away.

Section 7.2.2.2: dialogterminate Attribute Details
Attribute Name Details
dialogid is an ECMAScript expression which returns a character string identifying the dialog. This dialogid was generated by <dialogstart> and stored in the ECMAScript variable identified by the "dialogid" attribute.
immediate Set to "true" or "false" to specify if the dialog is immediately terminated. The default is "false".

Section 7.3: Events

Section 7.3.1: Overview

CCXML and Dialogs do most of their communication using events. In the case where CCXML is receiving a event from a dialog it gets input into the CCXML applications event queue.

A CCXML application can also send a event to a dialog. How this is handled on the dialog side is dialog language dependent. On the CCXML side it is done by using the <send> tag and passing in the dialogid that was received on the <dialogstart> tag.

The following are the CCXML events that have to do with dialogs:

Section 7.3.2: dialog.started

This event is thrown when a dialog is started.

The fields of this event are:

Field Name Details
name dialog.started
dialogid The ID of the dialog returned from <dialogstart>
callid The called of the phone call that this dialog is executing on.

Section 7.3.3: dialog.exit

This event is thrown when a dialog exits.

The fields of this event are:

Field Name Details
name dialog.exit
dialogid The ID of the dialog returned from <dialogstart>
callid The called of the phone call that this dialog is executing on.
namelist List of items that are stored on the "values" sub-object.
values.* Values returned from the dialog.

Section 7.3.4: dialog.disconnect

This event is thrown when a dialog requests the call to be disconnected. It does not terminate the dialog but is only a request into the CCXML application to end the call.

The fields of this event are:

Field Name Details
name dialog.disconnect
dialogid The ID of the dialog returned from <dialogstart>
callid The called of the phone call that this dialog is executing on.
namelist List of items that are stored on the "values" sub-object.
values.* Values returned from the dialog.

Section 7.3.5: dialog.transfer

This event is thrown when a dialog is requesting the call to be transferred.

The fields of this event are:

Field Name Details
name dialog.transfer
dialogid The ID of the dialog returned from <dialogstart>
callid The called of the phone call that this dialog is executing on.
type A string value specifying the transfer type.
url The URL to transfer to.
namelist List of items that are stored on the "values" sub-object.
values.* Dialog transfer parameters. This is where a dialog language can specify more information about the transfer request. For example with VoiceXML could contain all the attributes of the <transfer> tag.

Section 7.3.6: error.dialog.notstarted

This event is thrown when a dialog can not be started for some reason.

The fields of this event are:

Field Name Details
name error.dialog.notstarted
dialogid The ID of the dialog returned from <dialogstart>
callid The called of the phone call that this dialog is executing on.
reason A description of the reason the dialog could not be started.

Section 7.3.7: error.dialog.wrongstate

This event is thrown when a dialog request was received and could not be completed because we are in a improper state.

The fields of this event are:

Field Name Details
name error.dialog.wrongstate
dialogid The ID of the dialog returned from <dialogstart>
callid The called of the phone call that this dialog is executing on.
reason A description of the reason the dialog is in the wrong state.

Section 7.3.8: dialog.user.*

This event is thrown when a dialog sends a user event to the CCXML application.

The fields of this event are:

Field Name Details
name dialog.user.*
dialogid The ID of the dialog returned from <dialogstart>
callid The called of the phone call that this dialog is executing on.
namelist List of items that are stored on the "values" sub-object.
values.* The contents of the event.

Section 8: Variables and Expressions

Section 8.1: Overview

Section 8.2: Tags

Section 8.2.1: <assign> and <var>

Section 8.2.1.1: Overview

CCXML variables and expressions are similar to those in VoiceXML. All expressions must be valid ECMAScript expressions, assignable to variables with valid ECMAScript names.

Variables are declared explicitly by the var element:

<var name="sessionid" />
<assign name="currentstate" expr="initial"/>

Variables declared without an explicit initial value are initialized to the ECMAScript undefined value. Variables must be declared before being used.  However, see the <assign> element for a discussion of implicit declaration.

A variable is declared with the scope of the closest containing scope element. The fully-qualified name of a variable is the name of the variable's scope object prepended with a dot to the name of the variable. Within the attribute values of CCXML elements, variables can be referenced without their full qualification, which is implied. In the case of like-named variables declared in different scopes, the closest containing scope is implied, unless a fully-qualified variable name is used.  If a variable is declared more than once, declarations subsequent to the first are considered to be assignments of the expr attribute initializer value to the variable.  The default initializer is the ECMAScript value undefined .

Assignment to a variable which is undeclared at the point of the assignment implicitly declares that variable. The variable is declared in the scope of its closest containing scope element, and is known from the point of the assignment to the end of the scope.

Variables are declared using var element and assigned a value either at declaration time, or later through the assign element.

Section 8.2.1.2: Var Attribute Details
Attribute Name Details
name Indicates the name of the variable. It should be a valid ECMAScript variable name.
expr Indicates the new value of the variable. This is the initial value. It can be any valid ECMAScript expression.
Section 8.2.1.3: Assign Attribute Details
Attribute Name Details
name is an ECMAScript left-hand-side expression.
expr Indicates the new value of the variable. It can be any valid ECMAScript expression.

Section 8.2.2: <script>

Section 8.2.2.1: Overview

The <script> element encloses computations written in the ECMAScript Compact Profile (ECMA-327) scripting language. For example, this <script> element defines a function that computes the greatest common factor of two integers:

<script>
function gcd(a, b)
{
 var t;
 if (a < 1 || b < 1)
   return -1;
 do
  {
   t = a % b;
   a = b;
   b = t;
  }
 while (b > 1);
 return (b == 0) ? a : b;
}
</script>

A <script> element may occur in a <ccxml> element and in executable content. <transition> elements and <if> elements contain executable content. Script elements in a <ccxml> element are evaluated just after the document is loaded, along with the <var> and <assign> elements, in document order. Script elements in a <transition> element are evaluated as they are encountered. A <script> element in an <if> element is executed like other executable elements, as it is encountered.

A <script> element can declare variables with the ECMAScript var statement. Variables declared in this manner are in the scope of the closest containing scope element.  They are known from the point of declaration to the end of the containing scope.  The variables may be referenced with or without the qualification of their scope object.  If a variable is declared more than once, declarations subsequent to the first are considered to be assignments of the initializer value to the variable.  The default initializer is the ECMAScript value undefined

Section 8.2.2.2: script Attribute Details
Attribute Name
Details
src
a URI-valued ECMAScript expression which references a resource which is the script content, and which will be resolved when the CCXML document is compiled; if this attribute is not present, the script element's CDATA provides the script content

Section 9: Event Handling

Information on eventhandler , send , transition and move

Section 9.1: Event Concepts

Event Handling is one of the most powerful features of CCXML, and one way in which it is markedly different from VoiceXML. CCXML events have little to do with VoiceXML's nomatch and filled events. VoiceXML events only occur within well-defined contexts, and are generated by the task at hand; it's impossible to receive a recognition-related event except within a field inside a form . CCXML events, however, can be delivered at any time and from a variety of sources. This flexible event-handling mechanism is essential for many telephony applications.

Every CCXML program can receive events. These might be in response to a previous action by the CCXML program (e.g., an outbound-call request, which generates an event to indicate when the call goes off-hook), or on the initiative of some external source (e.g., an incoming call to be answered). Events can be generated by the telephony system (as in the two previous examples), other CCXML programs (which emit events via the send tag), or the CCXML recipient-interpreter (by sending an event to itself). There is a core set of telephony-related events (derived from the JTAPI/JCP/JCC event model. See JSR021 and JSR 034 from the sun web site) that a browser must generate. Implementers are otherwise free to define and generate any platform-specific events they like. In addition, users/programmers may use the send tag to send arbitrary events to external destinations, or may send arbitrary events to CCXML scripts from internal or external sources and may specify transition handlers to handle these events.

Each running CCXML interpreter has a queue, into which it places incoming events, and sorts them by arrival time. A CCXML programmer can only gain access to these queued events by using an eventhandler .

eventhandler elements are interpreted by an implicit Event Handler Interpretation Algorithm (EHIA). The EHIA's main loop removes the first event from the CCXML program's event queue, and then selects from the set of transition elements contained in the eventhandler . A transition element always indicates a set of accepted event types, and may indicate a further ECMAScript conditional expression to be evaluated. The transition element that accepts the type for the just-removed event, has a satisfied conditional expression (or none at all), and appears first in the eventhandler by document order, is the selected transition .

Once selected, the tags inside a transition element are executed in document order. At most, one transition will be chosen. If no transition elements meet all the criteria, none are selected and the event is simply dropped; the EHIA loop then starts over again, removing the first most event from the queue. Any events that arrive while an event is already being processed are just placed on the queue for later. If the event queue is empty, and the EHIA wants to process an event, execution pauses until an event arrives.

Code inside an eventhandler should run "instantaneously", without blocking execution. This will allow events to be rapidly processed.

The only way for CCXML execution to leave an eventhandler is via an explicit goto inside a transition .

An eventhandler may also declare a state variable. An eventhandler 's state variable is used just as any other variable, but with a scope limited to the eventhandler and its elements. The eventhandler can be considered, and programmed as, a finite-state-automaton, with the state variable indicating the automaton's current state or node, and the transition elements, driven by incoming events, moving the machine to a new state and creating side effects along the way. We expect, but CCXML does not require, that each transition will contain an assignment to the state variable to drive the automaton to its next state.

Issue Note:

There may be default transitions that handle common events, such as an incoming call or a dialogs exiting. It's not yet clear which events should have default handlers.

Section 9.2: Tags

Section 9.2.1: <eventhandler>

Section 9.2.1.1: eventhandler Attribute Details
Attribute Name Details
id The name of the eventhandler.
statevariable is a CCXML variable name which is the name of the <eventhandler> 's state variable.

Eventhandler elements can contain only transition elements.

Section 9.2.2: <transition>

Section 9.2.2.1: transition Attribute Details
Attribute Name Details
state Indicates the current possible state(s) of the eventhandler.
event is an ECMAScript expression returning a string that indicates a matching event type. Event types are dot-separated strings of arbitrary length. The character * is a wildcard, and will match zero or more characters of the processed-event's type name.
cond An ECMAScript expression that evaluates to true or false. If this attribute is present, it must evaluate to true for the transition to be selected.
The default value is true.
name is an ECMAScript left-hand-side expression that is set to the received event

Section 9.2.3: <send>

Section 9.2.3.1: Overview

It's now clear how CCXML can receive, process, and respond to external events. But it's not obvious how CCXML can generate those events directly. For that, we need the send tag. When the interpreter encounters a send , it will generate and deliver an event of the specified type to an indicated CCXML program. The set of addressable CCXML programs is up to the browser implementer, but at least all CCXML programs running within the same browser must be able to send events to each other.

Section 9.2.3.2: send Attribute Details
Attribute Name Details
event is an ECMAScript expression returning a string that indicates the type of event being generated. The event type may include alphanumeric characters and the "." (dot) character. The first character may not be a dot or a digit. Event type names are case-insensitive.
target is an ECMAScript expression returning a handle for the target CCXML program. This should be a globally-unique identifier, in a still-to-be-specified URI format. It is valid for a CCXML program to send an event to itself.
name is an ECMAScript left-hand-side expression that is the target for the event identifier. The unique identifier for the generated event is written to the target. If not present, the event's identifier is dropped.
delay is an ECMAScript expression returning a string in CCS format interpreted as a time interval. The send tag will return immediately, but the event not dispatched until the delay interval elapses. Timers are useful for a wide variety of programming tasks, and can be implemented using this attribute.
namelist A list of zero or more CCXML variables to be included along with the event.

Section 9.2.4: <move>

Section 9.2.4.1: Overview

The move tag is used to add an event endpoint to an executing CCXML thread of control.   An event endpoint originates CCXML events.  When an endpoint is added to a thread of control, events originating from that endpoint will be delivered to that thread's currently executing CCXML document.

Section 9.2.4.2: move Attribute Details
Attribute Name Details
endpoint an ECMAScript expression which returns a call ID or a conference ID; The endpoints associated with this identifier will be moved to the target session.   This attribute is optional, and can be used in conjunction with the event attribute or without it.
event an ECMAScript expression which returns an event object;  The event endpoint from which the event object originated, if any, will be added to the target session.  The event will also be sent to the target session to provide a notification.  This attribute is optional, and can be used in conjunction with the endpoint attribute or without it.
sessionid an ECMAScript string expression that identifies the thread of control to which the endpoint will be added;

Issue:

Should the issuing thread of control be able to move only endpoints which are already associated with it? Should the issuing thread of control be able to continue to receive events originating from the endpoint being moved but not processed by the target document?

Section 9.3: Event Transmission

Many useful applications are only possible when events can be passed to an arbitrary CCXML program, regardless of browser. For example, a user could be notified about a failed remote print job, or transferred to a now-available remote operator. Both scenarios involve events generated from a remote location and delivered over a network to a CCXML program. CCXML browsers must be able to dispatch such events correctly.

The protocol for communicating these events is now undetermined, but will eventually be specified so we can guarantee interoperability between CCXML. (HTTP and SIP are two options for network protocol.) Encoding options include SOAP and Xforms. Whatever we decide, the protocol we choose must allow for the following:

Section 9.4: Standard Events

CCXML can generate arbitrarily-named events. While any event name is possible, there is a small set of well-known events that are generated as a matter of course, and which any telephone application should handle. There are two kinds of these events: telephony events, which abstract interaction with the phone network, and language events.

The first, and larger set, is present so CCXML can keep abreast of what's happening with the telephone network. CCXML is designed to be neutral with respect to the telephony layer, so the event set we choose must be very generic and capable of describing the behavior of a wide variety of systems (e.g., Q931, SS7, VoIP, etc).

For now, we've chosen the JavaSoft JCP event model. It abstracts away many of the differences between the networks mentioned above, but does not offer much functionality. There may be better models than JCP, but it fits the bill for what we need at the moment: a small and easily-understood call model so we can write concrete sample programs. The ultimate choice of a standard model can be made later.

JCP was designed to be a cross-platform high-level event set to describe as generic a phone model as possible. The JCP/JCC call model consists of Addresses, Calls, Connections, and Providers. A Connection models the relationship between a single Call and a single Address. Neither value can change over the lifetime of the Call. A Call will maintain an association with zero or more Connections. It will have one Connection for every party in the call (so a two-party Call will have two Connections, and a four-party conference Call will have four).

All Calls are created by a Provider; the Call maintains an association with its Provider, which cannot change over the formers lifetime. Calls, Connections, and Providers all generate events, emitted when the object transitions to a new state.

Note that the JCC model is designed for endpoint devices only. Here is a fast description of the events. The descriptions and names are borrowed directly from the JavaSoft documentation.

Section 9.4.1: Call Class

The Call class emits events:

Section 9.4.2: Connection Class

The Connection class emits events:

Section 9.4.3: Provider Class

The Provider class emits events:

Section 9.4.4: Standard Events

The second, smaller set, is only for language purposes. Of these, there are a) events sent from dialogs, and b) events sent from the CCXML interpreter. The standard events are described here.

For dialog related events please see section 7.3 on dialog events.

This list will be extended as we discover new standard events.

Section 10: Telephony Operations and Resources

Information on accept , createcall , createconference , destroyconference , disconnect , join , redirect , reject , unjoin

The primary goal of CCXML is to provide call control throughout the duration of a call. Call control includes handling incoming calls, placing outgoing calls, bridging (or conferencing) multiple call legs, and ultimately disconnecting calls.

Section 10.1: Incoming Calls

Section 10.1.1: Overview

One of the events a CCXML document can receive is a call setup indication. A CCXML program interested in handling incoming calls will have an eventhandler transition block for execution. The transition block will either accept, reject, or redirect the incoming call using the <accept>, <reject> or <redirect> CCXML tags. The underlying platform will signal the telephony system appropriately, depending on the tag. Once the call is accepted, the CCXML document may initiate interactive dialog sessions with the incoming caller, or perform other telephony operations (e.g., place outgoing calls, join calls, etc).

Section 10.1.2: <accept>

Section 10.1.2.1: Overview

The <accept> tag will accept and connect an incoming phone call.

Section 10.1.2.2: accept Attribute Details
Attribute Name Details
callid is an ECMAScript expression which returns a string that is the id of the signaling incoming call leg that should be accepted. The callid attribute is optional; if omitted, the interpreter will accept using the id indicated in the current event being processed.
An accepted incoming call will result in the generation of a connection.CONNECTION_CONNECTED event.

Section 10.1.3: <redirect>

Section 10.1.3.1: Overview

The <redirect> tag will redirect an incoming phone call.

Section 10.1.3.2: redirect Attribute Details
Attribute Name Details
callid is an ECMAScript expression which returns a string that is the id of the signaling incoming call leg that should be redirected. The callid attribute is optional; if omitted, the interpreter will redirect using the id indicated in the current event being processed
dest is an ECMAScript expression which returns a string that is the target of the outbound telephone call. This should be a telephone URL, as described in http://www.ietf.org/rfc/rfc2806.txt
reason is an ECMAScript expression which returns a string that is the reason the call is being redirected

Section 10.1.4: <reject>

Section 10.1.4.1: Overview

The <reject> tag will reject an incoming phone call.

Section 10.1.4.2: reject Attribute Details
Attribute Name Details
callid is an ECMAScript expression which returns a string that is the id of the signaling incoming call leg that should be rejected. The callid attribute is optional; if omitted, the interpreter will reject using the id indicated in the current event being processed
reason is an ECMAScript expression which returns a string that is the reason the call is being rejected

Section 10.2: Outgoing Calls

Section 10.2.1: <createcall>

Section 10.2.1.1: Overview

A CCXML document can attempt to place an outgoing call with the createcall tag. This tag will instruct the platform to attempt to place an outgoing call to the indicated party. The tag is non-blocking, and the CCXML document is immediately free to perform other tasks, such as initiating dialog interaction with another caller. The CCXML interpreter will receive an asynchronous event when the call attempt is completed. An event handler transition block can handle this event and perform further call control, such as conferencing. If the call was successfully placed, the transition block can also initiate a dialog interaction with the called party.

Section 10.2.1.2: createcall Attribute Details
Attribute Name Details
dest is an ECMAScript expression which returns a string that is the target of the outbound telephone call. This should be a telephone URL, as described in http://www.ietf.org/rfc/rfc2806.txt
name is an ECMAScript left-hand-side expression that receives the outbound call leg's callid.

Section 10.3: Conferencing

The CCXML createconference tag can be used to create a conferencing object. This object is used to create multi-party conferences. Once created, the CCXML document can add call legs to the conference by using the join CCXML tag. Call legs can be removed by issuing the unjoin tag. A conference object can be destroyed using the destroyconference CCXML tag. Asynchronous events will be sent to the CCXML document upon completion of each of these operations.

Section 10.3.1: <createconference>

Section 10.3.1.1: createconference Attribute Details
Attribute Name Details
id is an ECMAScript left-hand-side expression that receives the conference identifier. A conference identifier should be globally unique, so that conferences can be uniquely addressed and possibly connected to. It should be in URI format.

Section 10.3.2: <destroyconference>

Section 10.3.2.1: destroyconference Attribute Details
Attribute Name Details
id is an ECMAScript expression which returns a string that is the identifier for the conference that should be destroyed.

Section 10.3.3: <join>

Section 10.3.3.1: join Attribute Details
Attribute Name Details
id1 is an ECMAScript expression which returns a conference object or a call leg identifier that is the first of two audio "endpoints" to join. This id can refer to a conference object, or a call leg. The interpreter will set up the underlying audio paths appropriately.
id2 is an ECMAScript expression which returns a conference object or a call leg identifier that is the second of two audio "endpoints" to join. This id can refer to a conference object or a call leg. The interpreter will set up the underlying audio paths appropriately. If both endpoints are call legs, they will be bridged. If one is a conference and the other a call leg, then the call leg will be added to the conference. The browser implementer may choose to fail in the case where both are conferences, or create and audio connection between the two conference objects.
duplex Equal to "half" or "full". A full-duplex connection allows both audio endpoints to hear each other. A half-duplex connection allows party 1 to hear party 2, but not vice-versa. If the attribute is not supplied, the join defaults to a full-duplex connection.

Section 10.3.4: <unjoin>

Section 10.3.4.1: unjoin Attribute Details
Attribute Name Details
id1 is an ECMAScript expression which returns a conference object or a call leg identifier that is the Id for the first audio endpoint we want to separate.
id2 is an ECMAScript expression which returns a conference object or a call leg identifier that is the Id for the second audio endpoint we want to separate. If both endpoints are call legs, they will be unbridged. If one is a conference and the other a call leg, then the call leg will be removed from the conference. See the description of join above for more on the two-conference case.

Section 10.4: Bridging

In many situations, the CCXML document may want to create a simple, two party call. In these cases, a separate conference is not needed. Instead, the CCXML document can use the join CCXML tag to bridge the two parties. The unjoin tag can be used to unbridge a previously bridged call. Asynchronous events will be sent to the CCXML document upon completion of both the join and unjoin operations.

Note that it is possible to transition from a bridged two party call to a multi-party conference by first using the createconference CCXML tag to create a conference object and then adding all of the parties to this conference. It is not possible to join a third call leg to an existing bridged call in order to create a 3-way call. If leg A is bridged to leg B, and then subsequently bridged to leg C, the result will be two 2-party calls, one between A and B and one between A and C.

Section 10.5: Coaching

Another common scenario in call center applications is the idea of a coach. Here, the 'coach' is a supervisor whose purpose is to eavesdrop on a conversation between the user and the support agent in order to allow to coach to 'whisper' advice to the agent. This functionality necessitates the ability to establish a two-way conference between the agent and the user, a two-way conference between the coach and the agent, and a listen-only conference between the coach and the user. Creating this type of conference is possible using the conferencing CCXML tags described above. However, it is also possible to do this by using a combination of the join and unjoin CCXML tags. This is accomplished by first using the join tag to bridge the user and the agent, as well as the agent and the supervisor. Once the join operations have completed, the CCXML program can use the join tag to setup a half-duplex connection between the supervisor and the user. These joined conversations can be undone using the unjoin CCXML tag.

Section 10.6: Disconnects

Section 10.6.1: <disconnect>

Section 10.6.1.1: Overview

A CCXML document may disconnect a call leg using the disconnect CCXML tag. The underlying platform will sent the appropriate protocol messages to perform the disconnect, and send an asynchronous event to the CCXML document when the disconnect operation completes.

Section 10.6.1.2: disconnect Attribute Details
Attribute Name Details
callid is an ECMAScript expression which returns a call leg identifier that is the id of the call leg that should be disconnected. The callid attribute is optional; if omitted, the interpreter will disconnect using the id indicated in the current event being processed.
reason is an ECMAScript expression which returns a string that is the reason the call is being rejected

A disconnected call will result in the generation of a connection.CONNECTION_DISCONNECTED event.

Section 11: Security

Section 11.1: Overview

In some environments, it may be necessary to authenticate scripts with the execution platform, and vice-versa.

The first aspect of the trust relationship between the script and the platform is whether or not the document server (web server) trusts the platform making the URL request for a CCXML script. This can be strengthened by (1) requiring the platform to use HTTPS (SSL-encrypted HTTP) instead of cleartext HTTP to fetch the script; and (2) by requiring HTTP-style user authentication, i.e., userid and password.

Section 11.2: <authenticate>

Section 11.2.1: Overview

The second aspect is whether or not the platform trusts the script. This can be strengthened by requiring scripts to contain an <authenticate> tag which provides information necessary to validate the script with the platform or an off-board authentication device such as a RADIUS server, SIP Proxy, or H.323 gatekeeper.

Section 11.2.2: authenticate Attribute Details
Attribute Name Details
server is an ECMAScript expression which returns the id of the server to authenticate with. This may be a URL, or an IP address and optional port id.
userid is an ECMAScript expression which returns the userid that the script will "login" as.
password is an ECMAScript expression which returns the password corresponding to the userid above.

If the authentication is successful, a ccxml.authenticated event will be generated. If the authentication is unsuccessful, a ccxml.exit event will be generated, causing the script to terminate (ccxml.exit events cannot be caught or ignored).

Issue Note:

It still need to be defined when exactley the authentication is preformed. This will be addressed in a future version of the spec.

Section 12: Examples

Example 1: Calling Card Application: Caller calls an 800 number and after some interaction with an IVR system places and outbound call to a friend.

Issue:

Need to add in support for the original caller to disconnect the call using a hot key.

-----------------
calling_card.ccxml

-----------------

<?xml version="1.0" encoding="UTF-8"?>

<ccxml version="1.0">
  <!-- Create our ccxml level vars -->
  <var name="in_callid" expr="''" />
  <var name="out_callid" expr="''" />

  <!-- Set our initial state -->
  <assign name="currentstate" expr="'initial'" />

  <eventhandler statevariable="currentstate">
    <!-- Deal with the incoming call -->
    <transition state="'initial'" event="connection.CONNECTION_ALERTING" name="evt">
      <assign name="in_callid" expr="evt.callid" />
      <accept callid="in_callid" />
    </transition>

    <transition state="'initial'" event="connection.CONNECTION_CONNECTED" name="evt">
      <assign name="currentstate" expr="'in_vxml_session'" />
      <!-- VoiceXML dialog is started on a separate thread - see pin.vxml -->
      <dialogstart callid="in_callid" src="'pin.vxml'" />
    </transition>

    <!-- happens when pin.vxml VoiceXML dialog thread exits -->
    <transition state="'in_vxml_session'" event="dialog.exit" name="evt">
      <createcall dest="evt.values.telnum" name="out_callid" />
      <assign name="currentstate" expr="'calling'" />
    </transition>

    <transition state="'calling'" event="connection.CONNECTION_FAILED" name="evt">
      <!-- tell the caller there was a error -->
      <dialogstart callid="in_callid" src="'error.vxml'" />
      <assign name="currentstate" expr="'oub_failed'" />
    </transition>

    <!-- happens when called party picks up the phone -->
    <transition state="'calling'" event="connection.CONNECTION_CONNECTED" name="evt">
      <assign name="out_callid" expr="evt.callid" />
      <!-- tell the callee he is receiving a call -->
      <dialogstart callid="out_callid" src="'callee.vxml'" />
      <assign name="currentstate" expr="'outb_ready_to_join'" />
    </transition>

    <transition state="'oub_failed'" event="dialog.exit" name="evt">
      <exit />
    </transition>

    <!-- happens when callee's vxml dialog (callee.vxml exits) -->
    <transition state="'outb_ready_to_join'" event="dialog.exit" name="evt">
      <join id1="in_callid" id2="out_callid" />
      <assign name="currentstate" expr="'wtg_for_joined'" />
    </transition>

    <transition state="'wtg_for_joined'" event="ccxml.joined" name="evt">
      <assign name="currentstate" expr="'active'" />
    </transition>

    <!-- Lets clean up the call  -->
    <transition event="call.CALL_INVALID" name="evt">
      <if cond="evt.callid == in_callid">
        <exit />
      </if>
    </transition>
  </eventhandler>
</ccxml>

----------------------
pin.vxml

-------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
  <form id="pin">
    <block> Welcome to Acme's Calling Card </block>
    <field name="pin" type="digits">
      <prompt> Please say your PIN number </prompt>
      <filled>
        <if cond="pin.length != 8">
          <clear namelist="pin"/>
        <else/>
          <assign name="application.pin" expr="pin" />
          <submit next="checktime.asp" namelist="pin"/>
        </if>
      </filled>
    </field>
  </form>
</vxml>
-------------------------
error.vxml

--------------------------
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
  <form>
    <block> 
        Sorry. The Party you are trying to call
        is unavailable. 
        <exit/>
    </block>
  </form>
</vxml>
-----------------------
callee.vxml

---------------------------
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
  <form>
    <block>You have a call. Connecting</block>
  </form>
</vxml>
----------------vxml doc output by 
checktime.asp

---------------
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
  <form id="form2">
    <!--.asp consults back-end database before filling this value-->
    <assign name="timeleft" expr="600"/>  
    <block> Time remaining is <value expr="timeleft"/> seconds </block>
    <field name="telnum" type="digits" >
      <prompt> Please speak the telephone number you want to call </prompt>
      <filled>
        <if cond="telnum.length != 7">
          <clear namelist="telnum"/>
        <else/>
          <exit namelist="telnum"/>
        </if>
      </filled>
    </field>
  </form>
</vxml>

Example 2: Conferencing application. Different callers call into a conference through an agreed upon telephone number. When each one of them joins the conference he is told how many people are there in the conference and those already in the conference are informed about a new entrant to the conference. Similarly when someone hangs up, the fact that a conference participant has exited is announced. A conference object is created at the beginning of the conference and is destroyed when all the participants have hung up.

<!-- 
First page

 to all callers -->


<?xml version="1.0" encoding="UTF-8"?>

<ccxml version="1.0">
  <var name="in_callid" expr="'''"/>
  <var name="currentstate" expr="'initial'"/>
  
  <eventhandler statevariable="currentstate">
    <transition state="'initial'" event="connection.CONNECTION_ALERTING" name="evt">
        <assign name="currentstate" expr="'alerting'"/>
        <assign name="in_callid" expr="evt.callid"/>
        <accept callid="in_callid"/>
    </transition>

    <transition state="'alerting'" event="connection.CONNECTION_CONNECTED" name="evt">
        <assign name="currentstate" expr="'fetching'"/>
        <fetch next="'http://acme.com/conference.asp'" namelist="in_callid"/>
    </transition>

    <transition state="'fetching'" event="fetch.done" name="evt">
        <goto fetchid="evt.fetchid"/>
    </transition>

</eventhandler>
</ccxml>

==========================================================================
<!-- 
ccxml page returned by conference.asp to first caller's
browser

-->

<?xml version="1.0" encoding="UTF-8"?>
<ccxml version="1.0" >

  <var name="conf_id" expr="'''"/>
  <var name="currentstate" expr="'starting'"/>
  <var name="in_callid" expr="'0f0c0d@host1.com'"/>
  <!-- above value is the value submitted to conference.asp-->

<eventhandler statevariable="currentstate">

    <transition state="'starting'" event="ccxml.loaded" name="evt">
        <createconference id="conf_id"/>
    </transition>

    <transition state="'starting'" event="ccxml.conferencecreated" name="evt">
        <assign name="currentstate" expr="'fetching'"/>
        <fetch next="'http://acme.com/conference.asp'" namelist="in_callid conf_id"/>
    </transition>

    <transition state="'fetching'" event="fetch.done" name="evt">
        <goto fetchid="evt.fetchid"/>
    </transition>

</eventhandler>
</ccxml>

==========================================================================
<!-- 
ccxml page returned by conference.asp to all callers


(incl first after the above page to create a conference has
been sent to the first caller) -->

<?xml version="1.0" encoding="UTF-8"?>
<ccxml version="1.0">
  <var name="currentstate" expr="'ready_to_conf'"/>
  <var name="in_callid" expr="'ff0d01@host2.com'"/>
  <var name="conf_id" expr="'0a4602@host1.com'"/>

    <!-- above values are the values submitted to conference.asp-->
    <eventhandler statevariable="currentstate">

    <transition event="ccxml.loaded" name="evt">
        <dialogstart callid="in_sessionid" src="'vconference.asp'"/>
        <join id1="conf_id" id2="in_callid" />
        <dialogstart callid="conf_id" src="'newcaller.vxml'"/>
        <assign name="currentstate" expr="'active'" />
    </transition>

    <transition state="'active'" event="connection.CONNECTION_DISCONNECTED" name="evt">
      <dialogstart callid="conf_id" src="'leave.vxml'"/>
      <assign name="currentstate" expr="'fetching'"/>
      <fetch next="'http://acme.com/teardown.asp'" namelist="in_callid conf_id"/>
    </transition>

    <transition state="'fetching'" event="fetch.done" name="evt">
        <goto fetchid="evt.fetchid"/>
    </transition>
</eventhandler>
</ccxml>

==========================================================================
<!-- vxml page 
vconference.asp

 -->

<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
<form>
  <block> Welcome to the W3C conference. There are already
          <value expr="'3'"/> participants in the conference.
          <!--above value is based on count kept by vconference.asp-->
  </block>
</form>
</vxml>


==========================================================================
<!-- vxml page 
newcaller.vxml

 -->

<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
    <form>
        <block> A new participant has entered the conference. </block>
    </form>
</vxml>

==========================================================================
<!-- vxml page 
leave.vxml

 -->

<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
    <form>
        <block> Someone just left the conference. </block>
    </form>
</vxml>

==========================================================================
<!-- 
ccxml page returned by teardown.asp to all but the last
participant

 -->

<?xml version="1.0" encoding="UTF-8"?>

<ccxml version="1.0">
  <var name="currentstate" expr="'destroying'"/>
  <var name="conf_id" expr="'0a4602@host1.com'"/>
  <var name="in_callid" expr="'ff0d01@host2.com'"/>
  <!-- above values are the values submitted to teardown.asp-->
    <eventhandler statevariable="currentstate">
    <transition event="ccxml.loaded" name="evt">
      <exit/>     <!-- just exit and destroy the session -->
    </transition>
  </eventhandler>
</ccxml>

==========================================================================
<!-- 
ccxml page returned by teardown.asp to last participant

 -->

<?xml version="1.0" encoding="UTF-8"?>

<ccxml version="1.0">
  <assign name="currentstate" expr="'destroying'"/>
  <assign name="conf_id" expr="'0a4602@host1.com'"/>
  <assign name="in_sessionid" expr="'ff0d01@host2.com'"/>
    <!-- above values are the values submitted to teardown.asp -->
    <eventhandler statevariable="currentstate">
    <transition event="ccxml.loaded" name="evt">
      <destroyconference id="conf_id"/>
      <exit/>
    </transition>
  </eventhandler>
</ccxml>

Example 3: Call Center Customer Support Interactions Acme customer support line wants to run a customer information and support service which allows users to call in, interact with an automated menu system using DTMF and voice. When the customer reaches a menu which requires an operator, the customer is placed in a hold queue for an available operator.

Alternatively, if the customer requests an operator at any point Acme would like to allow the customer to either wait for an operator, or continue navigating the system while in the hold queue. If the customer continues interacting with the automated system while waiting, Acme would like to be able to interrupt periodically with status about the hold queue and offer the customer the option of canceling their request if their question has been answered by the automated system. When an operator is available, the customer's interactions are stopped and the operator is connected.

For training purposes, Acme would also like to be able to have a trainer listening when the customer is connected to the operator and the operator presses a special key to get the help of the trainer. This trainer could interrupt and provide hints to the new operator about how to answer the question. The customer would not be able to hear these hints.

----------------------
main.ccxml

-------------------------------

<?xml version="1.0" encoding="UTF-8"?>
<ccxml version="1.0">
    <assign expr="'initial'" name="currentstate"/>
    <assign expr="'default'" name="queuemode"/>
    <eventhandler statevariable="currentstate">
        <transition event="connection.CONNECTION_ALERTING" name="evt" state="'initial'">
            <!-- happens when the customer first calls the call
      center's 800 number -->
            <assign expr="evt.callerid" name="in_callerid"/>
            <assign expr="evt.session" name="in_session"/>
            <accept/>
        </transition>
        <transition event="connection.CONNECTION_CONNECTED" name="evt" state="'initial'">
            <!-- happens if our incoming call is finally connected -->
            <assign expr="'in_mainchoice'" name="currentstate"/>
            <!-- start a VoiceXML dialog with the caller
     (see mainchoice.vxml below) -->
            <dialogstart dialogid="dlg_mainchoice" src="'http://acme/mainchoice.vxml'"/>
        </transition>
        <transition event="dialog.exit" name="evt" state="'in_mainchoice'">
            <!-- happens when mainchoice.vxml dialog exits -->
            <if cond="evt.mainchoice == 'agent'">
                <assign expr="in_callerid" name="caller_telnum"/>
                <fetch namelist="caller_telnum" next="'http://acme/queue_call.asp'"/>
            </if>
            <!-- assume queue_call.asp (not shown) will interact with the
        call-center's call-queuing system to queue the call. It will also
        send queue status to ccxml program when it receives one from the
        call-queuing system and inform the ccxml program when an agent is
        is available through an inter-browser communication mechanism. 
        Note that we do this fetch but we never do a goto to transition
        to this document. This also may beable to be done using
        the <send/> tag instead. This needs to be better documented. -->
            <assign expr="'in_queue'" name="currentstate"/>
            <dialogstart dialogid="dlg_queue" src="'queue1.vxml'"/>
        </transition>
        <transition event="user.status" name="evt" state="'in_queue'">
            <!-- happens when status is received from an external program.
      Exit the customer's IVR interaction to announce the status of the
      queue -->
            <dialogterminate dialogid="dlg_queue"/>
        </transition>
        <transition event="dialog.exit" name="evt" state="'in_queue'">
            <!-- happens when we either exited the IVR interaction or the
      queue status, so depending on the queue mode we fall back in either
      one of them -->
            <if cond="queuemode == 'default'">
                <assign expr="'status'" name="queuemode"/>
                <dialogstart dialogid="dlg_queue" src="'queuestat.asp'"/>
            <else/>
                <assign expr="'default'" name="queuemode"/>
                <dialogstart dialogid="dlg_queue" src="'queue1.vxml'"/>
            </if>
        </transition>
        <transition event="user.agent_avail" name="evt" state="'in_queue'">
            <!-- happens if an agent is finally available, so we try
     to connect to her/him -->
            <createcall dest="evt.telnum" name="out_callid"/>
            <assign expr="'calling'" name="currentstate"/>
        </transition>
        <transition event="connection.CONNECTION_CONNECTED" name="evt" state="'calling'">
            <!-- happens when agent is connected and picks up the phone,
      so we have to terminate the queue dialog -->
            <assign expr="evt.callid" name="out_callid"/>
            <dialogterminate dialogid="dlg_queue"/>
        </transition>
        <transition event="dialog.exit" name="evt" state="'calling'">
            <assign expr="conversing" name="currentstate"/>
            <dialogstart src="'agent.asp'"/>
            <join duplex="'full'" id1="in_callid" id2="out_callid"/>
        </transition>
        <transition event="user.conf_supervisor" name="evt" state="'conversing'">
            <!-- connect to the supervisor -->
            <createcall dest="evt.telnum" name="sup_callid"/>
        </transition>
        <transition event="connection.CONNECTION_CONNECTED" name="evt" state="'conversing'">
            <join duplex="'half'" id1="in_callid" id2="sup_callid"/>
            <!-- supervisor can hear the customer
      but customer can't hear supervisor -->
            <join duplex="'full'" id1="out_sessionid" id2="sup_sessionid"/>
            <!-- agent and supervisor can hear each other -->
            <assign expr="'coaching'" name="currentstate"/>
        </transition>
        <transition event="connection.CONNECTION_DISCONNECTED" name="evt" state="'coaching'">
            <if cond="evt.sessionid==sup_sessionid">
                <!-- the supervisor hung up, kick out the supervisor -->
                <unjoin id1="in_sessionid" id2="sup_sessionid"/>
                <unjoin id1="out_sessionid" id2="sup_sessionid"/>
                <disconnect callid="sup_sessionid"/>
                <assign expr="conversing" name="currentstate"/>
            <else/>
                <!-- the customer or agent hung up -->
                <exit/>
            </if>
        </transition>
        <transition event="connection.CONNECTION_DISCONNECTED" name="evt">
            <!-- this cleans up all call legs and conference objects -->
            <exit/>
        </transition>
    </eventhandler>
</ccxml>

----------------------
mainchoice.vxml

-------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
  <form>
    <field name="mainchoice" >
      <prompt>Please press or say 0 to talk to an agent,
      1 for self service</prompt>
      <option dtmf="0" value="agent"> zero </option>
      <option dtmf="1" value="self" > one  </option>

      <filled>
        <if cond="mainchoice=='agent'">
          <exit namelist="mainchoice"/>
        <else/>
          <goto next="http://acme/ivr.vxml" /> <!-- not shown -->
        </if>
      </filled>
    </field>
  </form>
</vxml>

----------------------
queue1.vxml

-------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
  <form>
    <block>All our customer service agents are busy right now.
    Your call will be answered in the order that it was received.
    We will connect you to an agent when one becomes available.
    Meanwhile you can continue to use our automated system.
    <goto next="http://acme/ivr.vxml"/>
    </block>
  </form>
</vxml>

----------------------
queuestat.asp

-------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
  <form>
    <block>
    All our customer service agents are still busy. There are
     <value expr="num_queued"/> callers ahead of you in the
     queue. If the automated system has answered your question,
     you can hangup. Otherwise please continue to hold.
    </block>
  </form>
</vxml>

----------------------
agent.asp

-------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
  <form>
    <field name="attnkey" type="digits">
      <!-- give the agent the ability to contact supervisor
      by hitting the '#' key -->
      <option dtmf="#" value="supervisor" />
      <filled>
        <if cond="attnkey==supervisor">
          <send event="conf_supervisor" dest="ccxml" />
        <else />
          <clear namelist="attnkey" />
        </if>
      </filled>
    </field>
  </form>
</vxml>

Example 4: Personal Assistant This program is not exactly the same as the Personal Assistant text from the Use Case document. However, the Use Case text is somewhat confusing. Here, we present a Personal Assistant which operates as an automated answering service.

A subscriber to this service would receive a phone number to the automated service. When a caller wants to talk to the subscriber, he calls the given number. This automated system asks who the caller is, and records the audio. Then the system calls the current number of the target person, and asks if the call should be connected.

If so, the calls are bridged. If not, then the original caller is warned and disconnected.

----------------------
main.ccxml

-------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<ccxml version="1.0">
    <var expr="'initial'" name="currentstate"/>
    <var name="in_callid"/>
    <var name="dlg_onhold"/>
    <var name="out_callid"/>

    <eventhandler statevariable="currentstate">
        <transition event="connection.CONNECTION_ALERTING" name="evt" state="'initial'">
            <assign expr="evt.callid" name="in_callid"/>
            <accept/>
        </transition>
        <transition event="connection.CONNECTION_CONNECTED" name="evt" state="'initial'">
            <assign expr="'welcoming_caller'" name="currentstate"/>
            <dialogstart src="'welcome_message.vxml'"/>
        </transition>
        <transition event="dialog.exit" state="'welcoming_caller'">
            <!-- place the caller on hold -->
            <dialogstart dialogid="dlg_onhold" src="'holdmusic.vxml'"/>
            <!-- Contact the target.  The number here is server-generated -->
            <assign expr="'contacting_target'" name="currentstate"/>
            <createcall dest="'tel:+16505551212'" name="out_callid"/>
        </transition>
        <transition event="connection.CONNECTION_CONNECTED" name="evt"
state="'contacting_target">
            <!-- Ask the target if (s)he would like to accept the call -->
            <assign expr="'waiting_for_target_answer'" name="currentstate"/>
            <dialogstart src="'outbound_greetings.vxml'"/>
        </transition>
        <transition event="dialog.exit" name="evt" state="'waiting_for_target_answer'">
            <assign expr="evt.accepted" name="accepted"/>
            <if cond="accepted == 'false'">
                <!-- disconnect the called party
       (but still notify the other one) -->
                <disconnect/>
            </if>
            <assign expr="'stop_hold'" name="currentstate"/>
            <dialogterminate dialogid="dlg_onhold"/>
        </transition>
        <transition event="dialog.exit" name="evt" state="'stop_hold'">
            <if cond="accepted == 'false'">
                <dialogstart callid="in_callid" src="'vm.vxml'"/>
           <else/>
                <assign expr="'playing_connecting'" name="currentstate"/>
                <dialogstart callid="in_callid" src="'connecting.vxml'"/>
            </if>
        </transition>
        <transition event="dialog.exit" name="evt" state="'playing_connecting'">
            <join id1="in_callid" id2="out_callid"/>
            <assign expr="'talking'" name="currentstate"/>
        </transition>
        <transition event="connection.CONNECTION_DISCONNECTED" name="evt">
            <if cond="evt.callid == in_callid">
                <exit/>
            </if>
        </transition>
    </eventhandler>
</ccxml>

-----------------
welcome_message.vxml

-----------------
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
  <form>
    <record name="recording">
      <prompt>
        This is the Personal Assistant.
        Please state your name.
      </prompt>
      <filled>
        OK, thanks.
        <submit next="postRecordingAndExit.vxml"
        namelist="recording"/>
      </filled>
    </record>
  </form>
</vxml>

-----------------
outbound_greetings.vxml

-----------------
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
  <form>
    <field id="answer">
      <grammar src="yesnogrammar"/>
      <prompt>
        <audio>Hi, you have a message from</audio>
        <audio src="dynamicallyRecordedName.wav"/>
        <audio> Would you like to take it?  Say Yes, or No.</audio>
      </prompt>

      <filled>
        <if cond="answer==yes">
          <audio>OK, connecting.</audio>
          <assign name="willaccept" value="true"/>
          <exit namelist="willaccept"/>
        <elseif cond="answer==no" />
          <audio>OK, goodbye. </audio>
          <assign name="willaccept" value="false"/>
          <exit namelist="willaccept"/>
        </if>
      </filled>
    </field>
  </form>
</vxml>

-----------------
vm.vxml

-----------------
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
    <form>
      <prompt>Transferring you to voice mail. </prompt>
      <block>
        <goto next="voicemail.vxml" />
      </block>
    </form>
</vxml>

-----------------
connecting.vxml

-----------------
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
    <form>
      <prompt>Your party is ready.  Connecting... </prompt>
      <block>
        <exit />
      </block>
    </form>
</vxml>

-----------------
holdmusic.vxml

-----------------

<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">
    <form id="Form">
        <block>
            <prompt bargin="false">
                Laa Laa Laa Laa. Don't you love this funky beat. 
                Laa Laa Laa Laa. Don't you love this funky beat. 
            </prompt>
            <goto next="holdmusic.vxml"/>
        </block>
    </form>
</vxml>


<!-- postRecordingAndExit.vxml writes and exposes the WAV file,
and then exits.  It's not interesting enough to include here. -->

Appendix A - Future Study

While the current proposal of CCXML adequately addresses the requirements and scenarios that we can imagine for call control, there are still several issues left to resolve. These include:

Separately-executing CCXML programs may want to exchange information for any number of reasons. They could be bridging two calls, or work together as part of a larger, multi threaded call application. We have not specified how to get addresses of other CCXML programs on the same browser. We could also specify a protocol for CCXML programs on separate browsers to communicate. We need to discuss both issues further.

Asynchronous communication from the document server or the network to the voice browser is sometimes desirable to tell the voice browser that it needs to initiate an action. For example, if the caller has been put on hold pending the availability of an agent, the ACD or call router would like to asynchronously inform the voice browser when it should perform a bridge to the call center. This communication could take the form of an http request from the document server or the network to the voice browser. Servicing such requests could mean running a http server on the voice browser, but it could also be provided through other mechanisms, e.g. SIP. It is not clear whether this specification should even try to specify the mechanism, or simply leave the matter to browser Implementers.

Outbound Notification is the ability of a web application to initiate one or more telephone calls to different recipients in order to inform them of certain important events. For example, a traffic reports service could call its subscribers if there is an accident on their commute routes. A financial firm could offer a service where an application calls clients when certain financial events take place; e.g., when an interesting stock rises or drops past a certain value. After calling the client, the VoiceXML application could interact with the callee, allowing him to place trades or check other market conditions. For these scenarios, the web application must be able to asynchronously inform the voice browser that it should execute CCXML/VoiceXML documents at a specified URL. The CCXML and VoiceXML pages can then control the behavior of the voice browser and can make it place outbound calls. Again, it is not clear whether we should specify this interface, or leave the matter to browser Implementers.

The scenarios described above need further study before they can be included in the CCXML specification.

Appendix B - Related Work

CPL

The Call Processing Language (CPL) is an XML based language that can be used to describe and control Internet telephony services. Its focus is user scripting of call handling behavior for incoming calls. It is designed to be suitable for running on a server where users may not be allowed to execute arbitrary programs, and so is not Turing-complete.

The latest version of CPL can be found linked from the IETF IP Telephony (IPTEL) working group charter page .

CallXML

CallXML is a markup language created by Voxeo corporation that includes both voice and call-control functionality. Most of the following is from the CallXML 2.0 specification: CallXML is an XML based markup language used to describe the user interface of a telephone, voice over IP, or multi-media call application to a CallXML browser.

CallXML was designed to make it easy for web developers to create applications that can interact with and control any number or type of calls, including:

VoiceXML is designed to make it easy for web developers to create voice recognition based interfaces for either telephones or computer-based applications. As such, VoiceXML is an excellent solution for voice based applications which provide access to web content and information, including:

Because of the natural complexity associated with dealing with voice commands, VoiceXML uses a relatively complex form/field/grammar/filled interface model in its design. In contrast, CallXML uses a more simplified block / action / event interface model, which can be easier to learn and which allows for visual design tools which directly represent CallXML markup as simple flow-chart like user interfaces. See http://community.voxeo.com

TXML

TXML (Telera's Extensible Markup Language) is an XML based language designed by Telera for remotely controlling the behavior of Point of Presence (POP)call-centers. The POP call-center system is a Telera invention capable of answering, servicing, queuing and routing of calls at local points of presence to reduce communication costs of toll-free inbound contact centers.

TXML provides the syntax for the XML Pages, which are generated at the customer's application at the premises and used by a POP server to execute actions on behalf of the customer's contact center . The XML Pages are simple ASCII text files that are either stored in a Web server's directory at the premises or generated by scripts at the premises server. The XMLPages are requested from the premises server via HTTP requests made by a client on the POP gateway.

The language includes elements for

Go here for more Telera documentation.

SIP

SIP, the Session Initiation Protocol, is a signaling protocol for Internet conferencing, telephony, presence, events notification and instant messaging. As a signaling protocol, SIP sits "below" the application description level of VoiceXML and CCXML. We expect many CCXML and VoiceXML browsers to support SIP signaling. (These same comments apply to H.323 and MGCP/Megaco.)

Dynamicsoft has described a method for an application server to utilize a VoiceXML browser as a network resource. This is an interesting approach, but there still needs to be a mechanism for describing the call-control logic. An application server product from dynamicsoft provides language bindings in Java Servlets, CPL, and a general CGI interface.

See http://www.dynamicsoft.com/prod_sol/downloads/pdf/AppEngineNwkDecompMdl.pdf

Appendix C - CCXML DTD

Here is the CCXML DTD for your reference.
<?xml version='1.0' encoding='UTF-8' ?>

<!ENTITY % uri "CDATA">

<!ENTITY % version "NMTOKEN">

<!ENTITY % esvar "NMTOKEN">

<!ENTITY % esvars "CDATA">

<!ENTITY % expression "CDATA">

<!ENTITY % boolean "(true | false)">

<!ENTITY % content.type "CDATA">

<!ENTITY % duration "CDATA">

<!ENTITY % string "CDATA">


<!ENTITY % executable.content "accept | createcall | join | unjoin | createconference |
destroyconference | dialogstart | dialogterminate | send | disconnect | assign | var | script | if
| goto | fetch |  exit | redirect | move">


<!ELEMENT accept EMPTY>
<!ATTLIST accept  
    callid %expression;  '_event.callid' 
>

<!ELEMENT authenticate EMPTY>
<!ATTLIST authenticate  
    server  %expression;  #REQUIRED
    userid   %expression;  #REQUIRED
    password %expression;  #REQUIRED 
>

<!ELEMENT assign EMPTY>
<!ATTLIST assign  
    name %esvar;  #REQUIRED
    expr %expression;  #REQUIRED 
>

<!ELEMENT ccxml (assign | var | eventhandler | script)* >
<!ATTLIST ccxml  
    version %version;  #REQUIRED 
>

<!ELEMENT createcall EMPTY>
<!ATTLIST createcall  
    dest %expression;   #REQUIRED 
    name %esvar;            #IMPLIED
>

<!ELEMENT createccxml EMPTY>
<!ATTLIST createccxml  
    fetchid %expression;  #REQUIRED 
    start %expression;  #IMPLIED 
    sessionid %esvar;  #IMPLIED 
>

<!ELEMENT createconference EMPTY>
<!ATTLIST createconference  
    id  %esvar;  #REQUIRED 
>

<!ELEMENT destroyconference EMPTY>
<!ATTLIST destroyconference  
    id %expression; #REQUIRED 
>

<!ELEMENT dialogstart EMPTY>
<!ATTLIST dialogstart  
    callid   %expression;    '_event.dialogid'
    src      %expression;           #REQUIRED
    type     %content.type;  'application/xml+vxml'
    namelist %esvars;         #IMPLIED
    dialogid %esvar;         #IMPLIED
>

<!ELEMENT dialogterminate EMPTY>
<!ATTLIST dialogterminate  
    dialogid  %expression;  '_event.dialogid'
    immediate  (true | false )  'false' 
>

<!ELEMENT disconnect EMPTY>
<!ATTLIST disconnect  
    callid %expression;  '_event.callid' 
    reason %expression;  #IMPLIED
>

<!ELEMENT else (%executable.content; | elseif | else)*>

<!ELEMENT elseif (%executable.content; | elseif | else)*>
<!ATTLIST elseif  
    cond %expression;  #REQUIRED 
>

<!ELEMENT eventhandler (transition)*>
<!ATTLIST eventhandler  
    id    ID       #IMPLIED
    statevariable  %esvar;  #REQUIRED 
>


<!ELEMENT exit EMPTY>
<!ATTLIST exit  
    expr     %expression;   '0'
    namelist %esvars;  #IMPLIED 
>

<!ELEMENT fetch EMPTY>
<!ATTLIST fetch  
    next     %expression;   #REQUIRED
    namelist %esvars;  #IMPLIED 
    method (get | post) 'get'
    fetchid %esvar; #IMPLIED
    sync %esvar; #IMPLIED
>

<!ELEMENT goto EMPTY>
<!ATTLIST goto  
    fetchid  %expression;  #REQUIRED 
>

<!ELEMENT if (%executable.content; | elseif | else)*>
<!ATTLIST if  
    cond %expression;  #REQUIRED 
>

<!ELEMENT join EMPTY>
<!ATTLIST join  
    id1    %expression;  #REQUIRED
    id2    %expression;  #REQUIRED
    duplex  %expression;  'full' 
>

<!ELEMENT move EMPTY>
<!ATTLIST move   
    endpoint    %expression;     #IMPLIED
    event       %expression;        #IMPLIED
    sessionid   %expression;     #REQUIRED
>

<!ELEMENT redirect EMPTY>
<!ATTLIST redirect  
    callid %expression;  '_event.callid'
    dest   %expression;    #REQUIRED
    reason %expression;  #IMPLIED 
>

<!ELEMENT reject EMPTY>
<!ATTLIST reject  
    reason %expression;  #IMPLIED
    callid %expression;  '_event.callid' 
>


<!ELEMENT script (#PCDATA)*>
<!ATTLIST script  
    src %expression;  #IMPLIED 
>

<!ELEMENT send EMPTY>
<!ATTLIST send  
    event    %expression;        #REQUIRED
    target   %expression;             #IMPLIED
    name     %expression;        #IMPLIED
    delay    %duration;     #IMPLIED
    namelist %esvars;  #IMPLIED 
>


<!ELEMENT transition (%executable.content;)*>
<!ATTLIST transition  
    state %string;       #IMPLIED
    event %expression;       #REQUIRED
    cond  %expression;  #IMPLIED
    name  %esvar;       #IMPLIED
>


<!ELEMENT unjoin EMPTY>
<!ATTLIST unjoin  
    id1 %expression;  #REQUIRED
    id2 %expression;  #REQUIRED 
>

<!ELEMENT var EMPTY>
<!ATTLIST var  
    name %esvar;  #REQUIRED
    expr %expression;  #IMPLIED 
>

Appendix D - CCXML Schema

Here is the CCXML Schema for your reference.
<?xml version = "1.0" encoding = "UTF-8"?>
<xsd:schema xmlns:xsd = "http://www.w3.org/2000/10/XMLSchema">
    <xsd:group name = "executable.content">
        <xsd:choice>
            <xsd:element ref = "accept"/>
            <xsd:element ref = "createcall"/>
            <xsd:element ref = "join"/>
            <xsd:element ref = "unjoin"/>
            <xsd:element ref = "createconference"/>
            <xsd:element ref = "destroyconference"/>
            <xsd:element ref = "dialogstart"/>
            <xsd:element ref = "dialogterminate"/>
            <xsd:element ref = "send"/>
            <xsd:element ref = "disconnect"/>
            <xsd:element ref = "assign"/>
            <xsd:element ref = "var"/>
            <xsd:element ref = "script"/>
            <xsd:element ref = "if"/>
            <xsd:element ref = "goto"/>
            <xsd:element ref = "fetch"/>
            <xsd:element ref = "exit"/>
            <xsd:element ref = "redirect"/>
            <xsd:element ref = "move"/>
        </xsd:choice>
    </xsd:group>
    <xsd:element name = "accept">
        <xsd:complexType>
            <xsd:attribute name = "callid" use = "default" value = "_event.callid" type =
"xsd:%expression;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "authenticate">
        <xsd:complexType>
            <xsd:attribute name = "server" use = "required" type = "xsd:%expression;"/>
            <xsd:attribute name = "userid" use = "required" type = "xsd:%expression;"/>
            <xsd:attribute name = "password" use = "required" type = "xsd:%expression;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "assign">
        <xsd:complexType>
            <xsd:attribute name = "name" use = "required" type = "xsd:%esvar;"/>
            <xsd:attribute name = "expr" use = "required" type = "xsd:%expression;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "ccxml">
        <xsd:complexType>
            <xsd:choice minOccurs = "0" maxOccurs = "unbounded">
                <xsd:element ref = "assign"/>
                <xsd:element ref = "var"/>
                <xsd:element ref = "eventhandler"/>
                <xsd:element ref = "script"/>
            </xsd:choice>
            <xsd:attribute name = "version" use = "required" type = "xsd:%version;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "createcall">
        <xsd:complexType>
            <xsd:attribute name = "dest" use = "required" type = "xsd:%expression;"/>
            <xsd:attribute name = "name" type = "xsd:%esvar;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "createccxml">
        <xsd:complexType>
            <xsd:attribute name = "fetchid" use = "required" type = "xsd:%expression;"/>
            <xsd:attribute name = "start" type = "xsd:%expression;"/>
            <xsd:attribute name = "sessionid" type = "xsd:%esvar;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "createconference">
        <xsd:complexType>
            <xsd:attribute name = "id" use = "required" type = "xsd:%esvar;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "destroyconference">
        <xsd:complexType>
            <xsd:attribute name = "id" use = "required" type = "xsd:%expression;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "dialogstart">
        <xsd:complexType>
            <xsd:attribute name = "callid" use = "default" value = "_event.dialogid" type =
"xsd:%expression;"/>
            <xsd:attribute name = "src" use = "required" type = "xsd:%expression;"/>
            <xsd:attribute name = "type" use = "default" value = "application/xml+vxml" type =
"xsd:%content.type;"/>
            <xsd:attribute name = "namelist" type = "xsd:%esvars;"/>
            <xsd:attribute name = "dialogid" type = "xsd:%esvar;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "dialogterminate">
        <xsd:complexType>
            <xsd:attribute name = "dialogid" use = "default" value = "_event.dialogid" type =
"xsd:%expression;"/>
            <xsd:attribute name = "immediate" use = "default" value = "false">
                <xsd:simpleType>
                    <xsd:restriction base = "xsd:NMTOKEN">
                        <xsd:enumeration value = "true"/>
                        <xsd:enumeration value = "false"/>
                    </xsd:restriction>
                </xsd:simpleType>
            </xsd:attribute>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "disconnect">
        <xsd:complexType>
            <xsd:attribute name = "callid" use = "default" value = "_event.callid" type =
"xsd:%expression;"/>
            <xsd:attribute name = "reason" type = "xsd:%expression;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "else">
        <xsd:complexType>
            <xsd:choice minOccurs = "0" maxOccurs = "unbounded">
                <xsd:group ref = "executable.content"/>
                <xsd:element ref = "elseif"/>
                <xsd:element ref = "else"/>
            </xsd:choice>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "elseif">
        <xsd:complexType>
            <xsd:choice minOccurs = "0" maxOccurs = "unbounded">
                <xsd:group ref = "executable.content"/>
                <xsd:element ref = "elseif"/>
                <xsd:element ref = "else"/>
            </xsd:choice>
            <xsd:attribute name = "cond" use = "required" type = "xsd:%expression;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "eventhandler">
        <xsd:complexType>
            <xsd:sequence minOccurs = "0" maxOccurs = "unbounded">
                <xsd:element ref = "transition"/>
            </xsd:sequence>
            <xsd:attribute name = "id" type = "xsd:ID"/>
            <xsd:attribute name = "statevariable" use = "required" type = "xsd:%esvar;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "exit">
        <xsd:complexType>
            <xsd:attribute name = "expr" use = "default" value = "0" type =
"xsd:%expression;"/>
            <xsd:attribute name = "namelist" type = "xsd:%esvars;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "fetch">
        <xsd:complexType>
            <xsd:attribute name = "next" use = "required" type = "xsd:%expression;"/>
            <xsd:attribute name = "namelist" type = "xsd:%esvars;"/>
            <xsd:attribute name = "method" use = "default" value = "get">
                <xsd:simpleType>
                    <xsd:restriction base = "xsd:NMTOKEN">
                        <xsd:enumeration value = "get"/>
                        <xsd:enumeration value = "post"/>
                    </xsd:restriction>
                </xsd:simpleType>
            </xsd:attribute>
            <xsd:attribute name = "fetchid" type = "xsd:%esvar;"/>
            <xsd:attribute name = "sync" type = "xsd:%esvar;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "goto">
        <xsd:complexType>
            <xsd:attribute name = "fetchid" use = "required" type = "xsd:%expression;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "if">
        <xsd:complexType>
            <xsd:choice minOccurs = "0" maxOccurs = "unbounded">
                <xsd:group ref = "executable.content"/>
                <xsd:element ref = "elseif"/>
                <xsd:element ref = "else"/>
            </xsd:choice>
            <xsd:attribute name = "cond" use = "required" type = "xsd:%expression;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "join">
        <xsd:complexType>
            <xsd:attribute name = "id1" use = "required" type = "xsd:%expression;"/>
            <xsd:attribute name = "id2" use = "required" type = "xsd:%expression;"/>
            <xsd:attribute name = "duplex" use = "default" value = "full" type =
"xsd:%expression;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "move">
        <xsd:complexType>
            <xsd:attribute name = "endpoint" type = "xsd:%expression;"/>
            <xsd:attribute name = "event" type = "xsd:%expression;"/>
            <xsd:attribute name = "sessionid" use = "required" type = "xsd:%expression;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "redirect">
        <xsd:complexType>
            <xsd:attribute name = "callid" use = "default" value = "_event.callid" type =
"xsd:%expression;"/>
            <xsd:attribute name = "dest" use = "required" type = "xsd:%expression;"/>
            <xsd:attribute name = "reason" type = "xsd:%expression;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "reject">
        <xsd:complexType>
            <xsd:attribute name = "reason" type = "xsd:%expression;"/>
            <xsd:attribute name = "callid" use = "default" value = "_event.callid" type =
"xsd:%expression;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "script">
        <xsd:complexType>
            <xsd:simpleContent>
                <xsd:extension base = "xsd:string">
                    <xsd:attribute name = "src" type = "xsd:%expression;"/>
                </xsd:extension>
            </xsd:simpleContent>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "send">
        <xsd:complexType>
            <xsd:attribute name = "event" use = "required" type = "xsd:%expression;"/>
            <xsd:attribute name = "target" type = "xsd:%expression;"/>
            <xsd:attribute name = "name" type = "xsd:%expression;"/>
            <xsd:attribute name = "delay" type = "xsd:%duration;"/>
            <xsd:attribute name = "namelist" type = "xsd:%esvars;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "transition">
        <xsd:complexType>
            <xsd:choice minOccurs = "0" maxOccurs = "unbounded">
                <xsd:group ref = "executable.content"/>
            </xsd:choice>
            <xsd:attribute name = "state" type = "xsd:%string;"/>
            <xsd:attribute name = "event" use = "required" type = "xsd:%expression;"/>
            <xsd:attribute name = "cond" type = "xsd:%expression;"/>
            <xsd:attribute name = "name" type = "xsd:%esvar;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "unjoin">
        <xsd:complexType>
            <xsd:attribute name = "id1" use = "required" type = "xsd:%expression;"/>
            <xsd:attribute name = "id2" use = "required" type = "xsd:%expression;"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name = "var">
        <xsd:complexType>
            <xsd:attribute name = "name" use = "required" type = "xsd:%esvar;"/>
            <xsd:attribute name = "expr" type = "xsd:%expression;"/>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

Appendex E - VoiceXML Integration Details

Overview

This section describes the details of how CCXML and VoiceXML work together to provide dialog functionality in CCXML.

Events

CCXML and VoiceXML need to be able to exchange events between the browsers. The method of the message passing is up to the platform but it is assumed that there is some basic capacity in place.

One of the main areas that need to be dealt with is the VoiceXML application receiving random events. At this point until there are extensions to VoiceXML to allow this it is assumed there is only a limited amount of events that can be sent from the CCXML application to the VoiceXML application.

CCXML <dialogstart>

When a CCXML application processes a <dialogstart> tag it starts up a VoiceXML application on the call leg with the url that is passed in on the <dialogstart> tag.

CCXML <dialogterminate>

When a CCXML application processes a <dialogterminate> it causes a connection.disconnect event to be thrown to the VoiceXML application. As far as the VoiceXML application knows the call was just disconnected. The VoiceXML application still has a chance to return data to the CCXML application by using the <exit> tag in its <catch> statement.

VoiceXML <exit>

When a VoiceXML application processes a VoiceXML <exit> tag it will cause the VoiceXML application to exit and return the contents of the namelist attrubute to the CCXML application in the dialog.exit event in the following form:

      
      <exit namlist="foo bar jar"/><

maps into an event that looks like the following:

      dialog.exit
                 values.foo      
                 values.bar
                 values.jar

VoiceXML <disconnect>

When the VoiceXML application processes a <disconnect> tag it causes a dialog.disconnect event to be thrown in the CCXML application. It is then up to the CCXML application to disconnect the call and sends back a connection.disconnect event. The following is an example of what would happen:

  1. The VoiceXML script executes a <disconnect> element.
  2. As a result, the VoiceXML interpreter sends a< disconnect event to CCXML.
  3. CCXML receives a dialog.disconnect event from the VoiceXML script. It interprets this as a request from the VoiceXML script to "please disconnect me".
  4. An eventhandler in the CCXML script should have a <transition> element intended to handle the dialog.disconnect event.
  5. The CCXML application would have a <disconnect> tag as the child of the transition event. This would disconnect the call.
  6. The CCXML platform completes the disconnect function, dropping the call. The platform performs an upcall which could result in CCXML throwing the connection.CONNECTION_DISCONNECTED event.
  7. An eventhandler in the CCXML script should have a <transition> element intended to handle the connection.CONNECTION_DISCONNECTED event.
  8. The <transition> element has a child element which performs a <send> of the connection.disconnect.hangup event to the VoiceXML script.

Here is the sample CCXML code that completes the disconnect and returns the connection.disconnect event back to VoiceXML:

      <ccxml version="1.0">
        <eventhandler statevariable="mystate">

          <transition event="dialog.disconnect" name="myevent">
            <assign name="dialogid" expr="myevent.dialogid"/>
            <disconnect sessionid="myevent.callid" />
          </transition>

          <transition event="connection.CONNECTION_DISCONNECTED" >
            <send event="connection.disconnect.hangup" target="dialogid"/>
          </transition>

        </eventhandler>
      </ccxml>

VoiceXML <transfer>

When a VoiceXML application processes a <transfer> tag it is handled within CCXML via series of events between the VoiceXML platform and the CCXML application. Here is an example:

  1. The VoiceXML script executes a <transfer> element.
  2. As a result, the VoiceXML interpreter sends a transfer eventto CCXML. Included with the event is a namelist of the transfer element's attributes, e.g., the name of the form variable, the destination URI for the call to be transferred to, whether or not the call should be bridged or not, among others (see VoiceXML spec for complete list).
  3. CCXML receives a dialog.transfer event from the VoiceXML script. It interprets this as a request from the VoiceXML script to "please transfer me". Included with the event is the session ID of the call associated with the VoiceXML script, as well as all the transfer attributes described in step 2.
  4. An eventhandler in the CCXML script should have a <transition> element intended to handle the dialog.transfer event.
  5. Some child element of <transition> executes, invoking a <createcall> function to create an outgoing call leg.
  6. The CCXML platform completes the outgoing call function. This will cause a connection.CONNECTION_CONNECTED event.
  7. An eventhandler in the CCXML script should have a <transition> element intended to handle the connection.CONNECTION_CONNECTED event.
  8. The <transition> element has a child element which performs a <join> of the incoming call leg and the outgoing call leg.
  9. If the bridge attribute was false, then the original VoiceXML session script does not care to wait until the end of the new call for status. Send a telephone.disconnect.transfer event now to inform that session that the transfer is complete. This conforms to the behavior specified by VoiceXML 1.0 and 2.0.
  10. If the bridge attribute was true, then wait for the connection.CONNECTION_DISCONNECTED event to occur on the new call leg. Extract the disconnect reason, and now send that reason to the form variable in the original, blocked VoiceXML session as a dialog.vxml.transfer.complete event

dialog.vxml.transfer.complete

This event is sent from the CCXML application to the VoiceXML platform which uses this to fill transfer field item.

The fields of this event are:

Field Name Details
results.* The data that should be filled in on the VoiceXML field item.

Sample

Here is some sample CCXML code to handle the events related to a call transfer:

      <ccxml version="1.0">

        <var name="in_callid" />
        <var name="out_callid" />
        <var name="dialogid" />

        <eventhandler statevariable="mystate">
          <transition event="dialog.transfer" name="in_event">
            <assign name="mystate" expr="'calling_out'" />
            <assign name="in_callid" expr="in_event.callid" />
            <assign name="dialogid" expr="in_event.dialogid" />

            <createcall dest="in_event.url" name="out_callid" />
          </transition>

          <transition state="calling_out" event="connection.CONNECTION_CONNECTED"
name="out_event">
            <assign name="mystate" expr="'outgoing_call_active'" />
            <join sessionid1="in_callid" sessionid2="out_event.callid " duplex="full" />
            <if cond="in_event.values.bridge == 'false'">
              <send event="connection.disconnect.transfer" dest="dialogid"/>
            </if>
          </transition>

          <transition state="outgoing_call_active" event="connection.CONNECTION_DISCONNECTED"
name="out_event">
            <assign name="mystate" expr="'outgoing_call_finished'" />
            <if cond="in_event.bridge == 'true'">
              <if cond="in_event.callid == out_callid">
                <assign name="results" expr="far_end_disconnect" />
                <send event="dialog.vxml.transfer.complete" dest="in_event.dialogid"
namelist="results" />
              <else/>
                <send event="connection.disconnect.hangup" dest="dialogid" />
              </if>
            </if>
          </transition>
        </eventhandler><
      </ccxml>

User Disconnect

When a caller hangs up on one of the call legs the VoiceXML dialog is not automatically disconnected. You need to send a connection.disconnect.hangup event to the VoiceXML application so it can complete any cleanup that is required. The VoiceXML application can then still return data to the CCXML application by using the VoiceXML <exit> tag.

Issues:

Hotword:

We need to solve how hotword will be done in this setup. This may require some changes to how CCXML creates phone call legs and runs dialogs.

User Events

We need to add support for arbitrary user events between CCXML and VoiceXML in a future draft.

Default Handlers

We need to better define what if any default event handlers are in place for VoiceXML dialogs.

Proposed Enhancement to VoiceXML Event Handling

One of CCXML's main reasons to exist is VoiceXML's inability to process asynchronous events. When CCXML receives one of these events, it can process it silently, or start a new VoiceXML dialog. However, there are some occasions when we would like to tightly bind the event-processing with the user interface. In these cases, the VoiceXML author must be aware of event-processing, but gains very fine-grained control over dealing with the incoming event. In these cases, VoiceXML must be enriched with a notion of synchronous event handling.

We would like VoiceXML to be as ignorant as possible of the events being tossed back and forth. For generic interruptible and hold-music applications, <dialogstart> is enough. For interfaces which might change in response to arriving events (e.g., an option becomes 'unghosted' when a processing job completes), we need VoiceXML to be event-aware.

We can make VoiceXML process event input in much the same way as it handles speech input today. A new kind of form item can check the interpreter's pending synchronous events, and try to process the first one, if any. The form item selects one from its set of valid event handlers, and executes the code there. If there are no incoming synchronous events for some period of time, the form item can generate a NOINPUT, and process it appropriately.

This kind of event-handling is much less ambitious than the asynchronous variety we described above. However, when we want the dialog to change according to incoming events, we don't mind changing the VoiceXML code, and <dialogstart> is too blunt an instrument, processing synchronous events inside the dialog can be a useful approach.

Appendix F - Changes

Changes in working draft 2

Appendix G - Acknowledgments

This W3C specification is based upon CCXML 1.0 submitted in April 2001. The CCXML authors were:

This version was written with the participation of members of the W3C Voice Browser Working Group.