RFC 5707

Media Server Markup Language (MSML)

๐Ÿ“… published February 2010, from ietf

RFC 5707: Media Server Markup Language (MSML) ๐ŸŽ€

Okay bestie, here's the quick glow-up of the title block ๐Ÿ’… This is an Independent Submission, so it's not coming through the IETF stream. The category is Informational โœจ (not a Standards Track thing), and the ISSN is 2070-1721. It was published in February 2010 ๐ŸŒธ

The authors are A. Saleem and Y. Xin from RadiSys, plus G. Sharratt, who was a Consultant at the time ๐Ÿซถ The header doesn't list anything this RFC obsoletes or updates, so there's no drama there ๐Ÿ™ˆ


Abstract โœจ

MSML (Media Server Markup Language) is a language for controlling and invoking lots of different kinds of services on IP media servers ๐ŸŽง RadiSys started driving the MSML control interface, and then Intel, Dialogic, and other folks in the industry gave it a bunch of big contributions ๐Ÿ™Œ

With MSML, clients can decide how multimedia sessions interact on a media server, and they can apply services to one person or to a whole group ๐Ÿ‘‘ It's super handy for conference stuff like video layout and audio mixing, and it can also set up sidebar conferences, personal mixes, and the properties of media streams ๐ŸŽ€ Clients can also define media processing dialogs, which can be part of how apps interact with users or conferences ๐Ÿ’– Transforming media streams to and from users or conferences is one of those interactions, and so are interactive voice response (IVR) dialogs. MSML is what specifies all of this ๐Ÿฆ‹ On top of that, MSML clients can invoke dialogs with individual users or with groups of conference participants using VoiceXML ๐Ÿงš


Status of This Memo ๐Ÿ“œ

This document is not an Internet Standards Track specification. It's published just for informational purposes ๐ŸŒˆ

This is a contribution to the RFC Series, and it's independent of any other RFC stream ๐Ÿ’œ The RFC Editor picked to publish it at their own discretion, and they make no statement about how valuable it is for implementation or deployment ๐Ÿ“ Documents the RFC Editor approves for publication are not a candidate for any level of Internet Standard. See Section 2 of RFC 5741 for that โœจ

You can find info about the current status of this document, any errata, and how to give feedback at http://www.rfc-editor.org/info/rfc5707 ๐Ÿ”ฅ


IESG Note โš ๏ธ

This RFC is not a candidate for any level of Internet Standard. The IETF disclaims any knowledge of how fit this RFC is for any purpose. In particular, the decision to publish is not based on IETF review for things like security, congestion control, or inappropriate interaction with deployed protocols. The RFC Editor chose to publish this at their discretion, so readers should be careful when evaluating its value for implementation and deployment. See RFC 3932 for more information ๐Ÿ’€

Copyright (c) 2010 IETF Trust and the persons identified as the document authors. All rights reserved ๐Ÿ’–

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info), as they're in effect on the date this document was published. Please read these documents carefully, because they describe your rights and restrictions with respect to this document ๐Ÿ“œ


Table of Contents ๐Ÿ—บ๏ธ

1. Introduction ....................................................4
2. Glossary ........................................................5
3. MSML SIP Usage ..................................................6
   3.1. SIP INFO ...................................................7
   3.2. SIP Control Framework ......................................8
4. Language Structure .............................................15
   4.1. Package Scheme ............................................15
   4.2. Profile Scheme ............................................18
5. Execution Flow .................................................19
6. Media Server Object Model ......................................21
   6.1. Objects ...................................................21
   6.2. Identifiers ...............................................23
7. MSML Core Package ..............................................26
   7.1. <msml> ....................................................26
   7.2. <send> ....................................................26
   7.3. <result> ..................................................27
   7.4. <event> ...................................................27
8. MSML Conference Core Package ...................................28
   8.1. Conferences ...............................................28
   8.2. Media Streams .............................................29
   8.3. <createconference> ........................................31
   8.4. <modifyconference> ........................................33
   8.5. <destroyconference> .......................................34
   8.6. <audiomix> ................................................35
   8.7. <videolayout> .............................................36
   8.8. <join> ....................................................43
   8.9. <modifystream> ............................................45
   8.10. <unjoin> .................................................46
   8.11. <monitor> ................................................47
   8.12. <stream> .................................................47
9. MSML Dialog Packages ...........................................51
   9.1. Overview ..................................................51
   9.2. Primitives ................................................53
   9.3. Events ....................................................55
   9.4. MSML Dialog Usage with SIP ................................56
   9.5. MSML Dialog Structure and Modularity ......................57
   9.6. MSML Dialog Core Package ..................................58
   9.7. MSML Dialog Base Package ..................................63
   9.8. MSML Dialog Group Package .................................81
   9.9. MSML Dialog Transform Package .............................85
   9.10. MSML Dialog Speech Package ...............................88
   9.11. MSML Dialog Fax Detection Package ........................92
   9.12. MSML Dialog Fax Send/Receive Package .....................93
10. MSML Audit Package ...........................................100
   10.1. MSML Audit Core Package .................................100
   10.2. MSML Audit Conference Package ...........................102
   10.3. MSML Audit Connection Package ...........................106
   10.4. MSML Audit Dialog Package ...............................108
   10.5. MSML Audit Stream Package ...............................110
11. Response Codes ...............................................111
12. MSML Conference Examples .....................................113
   12.1. Establishing a Dial-In Conference .......................113
   12.2. Example of a Sidebar Audio Conference ...................117
   12.3. Example of Removing a Conference ........................118
   12.4. Example of Modifying Video Layout .......................118
13. MSML Dialog Examples .........................................120
   13.1. Announcement ............................................120
   13.2. Voice Mail Retrieval ....................................120
   13.3. Play and Record .........................................122
   13.4. Speech Recognition ......................................125
   13.5. Play and Collect ........................................125
   13.6. User Controlled Gain ....................................128
14. MSML Audit Examples ..........................................128
   14.1. Audit All Conferences ...................................128
   14.2. Audit Conference Dialogs ................................129
   14.3. Audit Conference Streams ................................130
   14.4. Audit All Connections ...................................131
   14.5. Audit Connection Dialogs ................................131
   14.6. Audit Connection Streams ................................132
   14.7. Audit Connection with Selective States ..................133
15. Future Work ..................................................134
16. XML Schema ...................................................134
   16.1. MSML Core ...............................................136
   16.2. MSML Conference Core Package ............................140
   16.3. MSML Dialog Packages ....................................148
   16.4. MSML Audit Packages .....................................170
17. Security Considerations ......................................176
18. IANA Considerations ..........................................176
   18.1. IANA Registrations for 'application' MIME Media Type ....176
   18.2. IANA Registrations for 'text' MIME Media Type ...........178
   18.3. URN Sub-Namespace Registration ..........................179
   18.4. XML Schema Registration .................................180
19. References ...................................................181
   19.1. Normative References ....................................181
   19.2. Informative References ..................................182
Acknowledgments ..................................................183

1. Introduction โœจ

Okay so media servers have these dynamic pools of media resources ๐ŸŽ€. Control agents and other users of media servers (called media server clients) can define and create tons of different services based on how they configure and use those resources ๐Ÿ’…. And honestly? That configuration, plus how the resources interact, often gets changed dynamically during a call to match how an app is interacting with a user ๐Ÿฆ‹.

For example, a call can start with an initial IVR dialog before it gets placed into a conference ๐ŸŽค. Calls can hop from a main conference to a sidebar conference and then back again ๐Ÿ’–. Individual calls can also be directly bridged to make small n-way calls or simple sidebars ๐ŸŒธ. None of these change the SIP [n1] dialog or RTP [i3] session ๐Ÿ™ˆ. Yet they all DO affect the media flow and processing inside the media server, so it's a whole vibe ๐Ÿ˜ญ.

The Media Server Markup Language (MSML) is an XML [n2] language used to control the flow of media streams, plus the services applied to those streams inside a media server ๐Ÿ‘‘. It's used to invoke lots of different types of services on individual sessions, groups of sessions, and conferences ๐Ÿงš. MSML lets you create conferences, bridge different sessions together, and bridge sessions into conferences ๐ŸŒˆ.

MSML can also create user interaction dialogs and allows media transforms to be applied to media streams โœจ. Media interaction dialogs made with MSML let you build IVR dialog sessions for individual users, as well as for groups of users in a conference ๐Ÿซถ. Dialogs can also be specified using other languages, like VoiceXML [n5], which supports complete single-party application logic executed on the media server ๐Ÿ’œ.

MSML is a transport independent language, so it doesn't rely on underlying transport mechanisms, and its language semantics are independent of transport ๐Ÿฆ‹. That said, SIP is a typical, commonly used transport mechanism for MSML, invoked using the SIP URI scheme ๐Ÿ’…. This specification defines using MSML dialogs with SIP as the transport mechanism ๐ŸŽ€.

A network connection can be established with the media server using SIP ๐Ÿ“ž. Media received and transmitted on that connection flows through different media resources on the media server, depending on the requested service ๐Ÿ“. Basic Network Media Services with SIP [n7] defines conventions for associating a basic service with a SIP Request-URI ๐ŸŒธ. MSML lets a control agent dynamically apply and change services during the lifetime of the SIP dialog ๐Ÿ”ฅ.

MSML was designed to handle control and manipulation of media processing operations (for example, announcement, IVR, play and record, automatic speech recognition (ASR), text to speech (TTS), fax, and video) ๐ŸŽ™๏ธ. It also handles control and relationships of media streams (for example, simple and advanced conferencing) ๐Ÿ‘ฏ. It provides a general-purpose media server control architecture ๐Ÿ‘‘. MSML can additionally be used to invoke other, more complex IVR languages such as VoiceXML ๐Ÿ’–.

The MSML control interface has been widely deployed across the industry, with numerous client-side and server-side implementations, since 2003 ๐Ÿฅน. The in-service commercial deployments cover a wide variety of applications, including (but not limited to) IP multimedia conferencing, network voice services, IVR, IVVR (interactive voice and video response), and voice/video mail ๐ŸŒˆ.


2. Glossary ๐Ÿ“–

  • Media Server: a general-purpose platform for executing real-time media processing tasks ๐Ÿงš. This is a logical function that maps either to a single physical device or to a portion of a physical device ๐Ÿ’œ.
  • Media Server Client: an application that originates MSML requests to a media server, also referred to as a control agent in this specification ๐Ÿซถ.
  • Network Connection: a participant that represents the termination on a media server of one or more RTP [i3] sessions (for example, audio and video) associated with a call ๐Ÿ“ž. Network connections are established and removed using a session establishment protocol such as SIP ๐Ÿ”ฅ. An instance of a network connection is independent of MSML processing instructions applied to it โœจ.
  • Dialog: an automated IVR participant ๐ŸŽ™๏ธ. Examples of dialogs may be announcement players, IVR interfaces, or voice recorders ๐ŸŽ€. Dialogs may be defined in MSML or using VoiceXML [n5] ๐Ÿ’….
  • Conference: an intermediary function that provides multimedia mixing and other advanced conferencing services ๐Ÿ‘ฏ. This specification currently considers conferences with audio and/or video media types, but is extensible to other media types ๐ŸŒธ.
  • Identifier: a name that is used to refer to a specific instance of an object on the media server, such as a conference or a dialog ๐Ÿ“. Identifiers are composed of one or more terms, where each term identifies an object class and instance ๐ŸŒˆ.
  • Object: the generic term for a media server entity that terminates, originates, or processes media ๐Ÿฆ‹. This specification defines four classes of objects and specifies mechanisms to create them, join them together, and destroy them ๐Ÿ‘‘.
  • Participant Object: an object in a media server that sources original media in a call and/or receives and terminates media in a call ๐Ÿ’–.
  • Intermediary Object: an object in a media server that acts on media within a call for the benefit of the participants ๐Ÿฅน.
  • Independent Object: an object that can exist on a media server independent of other objects ๐Ÿงš.
  • Operator: an intermediary transformer that modifies or transforms a media stream ๐Ÿ”ฅ. Examples of operators may be audio gain controls, video scaling, or voice masking ๐ŸŽ™๏ธ. MSML defines operators as media transform objects, which transform media using operations such as gain control, when applied to media streams ๐Ÿ’….
  • Media Stream: a single media flow between two objects ๐Ÿซถ. A media stream has a media type and may be unidirectional or bidirectional โœจ.

3. MSML SIP Usage ๐Ÿ“ž

SIP is used to create and modify media sessions with a media server according to the procedures defined in RFC 3261 [n1] ๐Ÿ’…. Often, SIP third party call control [i4] will be used to create sessions to a media server on behalf of end users ๐ŸŽ€. MSML is used to define and change the service that a user connected to a media server receives ๐Ÿฆ‹. MSML clients are application servers, soft-switches, or other forms of control agents, and they SHOULD have an authorized security relationship with the media server ๐Ÿ”. MSML itself does not define authorization mechanisms ๐Ÿ™…โ€โ™€๏ธ.

MSML transactions are originated based on events that occur in the application domain ๐ŸŒธ. These events may be independent from any media or user interaction ๐ŸŒˆ. For example, an application may want to play an announcement to a conference warning that its scheduled completion time is approaching ๐Ÿ“ข. Applications themselves are structured in lots of different ways ๐Ÿงฉ. Their structure and requirements contribute to their selection of protocols and languages ๐Ÿ’–. To accommodate differing application needs, MSML is designed to be neutral to other languages and independent of the transport used to carry it ๐Ÿ‘‘.

MSML is purposely designed to be transport independent ๐Ÿฆ‹. In this release of the specification, SIP INFO [i5] and SIP Control Framework [i11] have been chosen as transport mechanisms for MSML, as described in the following sections ๐ŸŽ€.

3.1. SIP INFO ๐ŸŽ€

SIP INVITE and INFO [i5] requests and responses MAY be used to carry MSML ๐Ÿ’…. INFO requests allow asynchronous mid-call messages within SIP with few additional semantics ๐ŸŒธ. Plus, there are existing widely deployed implementations of that method, it aids in initial developments that are closely coupled with SIP session establishment, and it allows MSML to be directly associated with user dialogs when third party call control is used ๐Ÿ™Œ.

Although INFO is sometimes considered not to be a suitable general-purpose transport mechanism for messages within SIP, there have been proposals to make it more acceptable ๐Ÿค”. MSML may evolve to include other SIP usage and/or to work with other protocols or as a stand-alone protocol established through SIP, in future releases of this document ๐Ÿ”ฎ.

MSML supports several models for client interaction ๐Ÿงš. When clients use 3PCC to establish media sessions on behalf of end users, clients will have a SIP dialog for each media session ๐Ÿ“ž. MSML MAY be sent on these dialogs ๐Ÿฆ‹. However, the targets of MSML actions are not inferred from the session associated with the SIP dialog ๐Ÿšซ. The targets of MSML actions are always explicitly specified using identifiers, as previously defined ๐ŸŽฏ.

An application, after interacting with a user, may want to affect multiple objects within a media server ๐Ÿ‘ฏ. For example, tones or messages are often played to a conference when connections are added or removed ๐Ÿ””. A separate message may also be played to a participant as they join, or to moderators ๐Ÿ’Œ. Explicit identifiers (that is, not inferred from a transport mechanism) allow these multiple actions to be easily grouped into a single transaction sent on any SIP dialog ๐Ÿ“.

MSML also supports a model of dedicated control associations ๐Ÿ‘‘. This supports decoupled application architectures, where a client can control media server services without also establishing all of the media sessions itself ๐Ÿฅฐ. Control associations are created using SIP, but they do not have any associated media session ๐Ÿ™ˆ. Although INFO messages will initially be sent on this SIP dialog, just as with dialogs associated with media sessions, it is possible that in the future, the SIP dialog will be used to establish a separate control session (defined in SDP [n9]) that does not use SIP as the transport for MSML messages ๐Ÿ”ฎ.

A media server using MSML also sends asynchronous events to a client using MSML scripts in SIP INFO ๐Ÿ’ซ. Events are sent based on previous MSML requests, and they are sent within the SIP dialog on which the MSML request that caused the event to be generated was received ๐Ÿ“ฌ. If this dialog no longer exists when the event is generated, the event is discarded ๐Ÿ—‘๏ธ.

Events may be generated during the execution of a dialog created by a <dialogstart> element ๐ŸŽ™๏ธ. For example, dialogs can send events based on user input ๐Ÿ‘‚. VoiceXML dialogs, on the other hand, generally interact with other servers outside of MSML using HTTP ๐ŸŒ.

An event is also generated when the execution of a dialog terminates, because of either completion or failure โœ…. The exact information returned depends on the dialog language, the capabilities of the dialog execution environment, and what was requested by the dialog ๐Ÿงพ. Both MSML and VoiceXML [n5] allow information to be returned when they exit ๐Ÿ“ค. These events may be sent in a SIP INFO or a SIP BYE ๐Ÿ“จ. SIP BYE is used when the dialog itself specifies that the connection should be disconnected, for example, through the use of the <disconnect> element ๐Ÿ‘‹.

Conferences may also generate events based upon their configuration ๐ŸŽช. An example of this is the notification of the set of active speakers ๐Ÿ—ฃ๏ธ.

3.2. SIP Control Framework โœจ

okay so the SIP Control Framework [i11] MAY be used as a transport mechanism for MSML ๐Ÿšš๐Ÿ’จ it's basically a delivery truck for MSML commands

the Control Framework gives you a generic way to set up and report on remotely started commands ๐Ÿ“ฆ it leans on a bunch of stuff from the Session Initiation Protocol (SIP) [n1] to find its partner and set up a reliable channel for back-and-forth control chats ๐Ÿซถ and honestly? compared to SIP INFO, this one is the more general-purpose option ๐Ÿ’… it isn't stuck with the limits that SIP INFO has, so it's giving freedom ๐Ÿฆ‹

the framework also brings in the idea of a Control Package ๐ŸŽ€ that's basically a specific, explicit way of using the Control Framework for one particular set of interactions. this spec already defines a bunch of packages so MSML can control the media server in lots of ways ๐ŸŒˆ we're talking basic dialog, advanced conferencing, advanced dialog, and audit service ๐Ÿ‘‘ every one of these packages gets its own unique Control Package name so MSML can be used with the Control Framework ๐Ÿงš

this section is where we cover the mandatory info that MUST be specified when you define a Control Framework Package, as laid out in SIP Control Framework [i11] ๐Ÿ“ no skipping this one, bestie ๐Ÿ˜ญ

3.2.1. Control Framework Package Names

the Control Framework [i11] says every Control Package definition has to specify and register a unique name ๐Ÿ”ฅ

the MSML spec uses a hierarchical naming scheme so you can see which packages inherit from which ๐ŸŒธ for example, package "msml-x" is derived from package "msml", and package "msml-x-y" is derived from package "msml-x" ๐Ÿง  it's like a family tree, iykyk ๐ŸŒณ

here's the list of Control Package names that the MSML spec reserves ๐Ÿ’–

"msml": this Control Package supports MSML Core Package as specified
   in section 7.

"msml-conf": this Control Package supports MSML Conference Core
   Package as specified in section 8.

"msml-dialog": this Control Package supports MSML Dialog Core Package
   as specified in section 9.6.

"msml-dialog-base": this Control Package supports MSML Dialog Base
   Package as specified in section 9.7.

"msml-dialog-group": this Control Package supports MSML Dialog Group
   Package as specified in section 9.8.

"msml-dialog-transform": this Control Package supports MSML Dialog
   Transform Package as specified in section 9.9.

"msml-dialog-speech": this Control Package supports MSML Dialog
   Speech Package as specified in section 9.10.

"msml-dialog-fax-detect": this Control Package supports MSML Dialog
   Fax Detection Package as specified in section 9.11.

"msml-dialog-fax-sendrecv": this Control Package supports MSML Dialog
   Fax Send/Receive Package as specified in section 9.12.

"msml-audit": this Control Package supports MSML Audit Core Package
   as specified in section 10.1.

"msml-audit-conf": this Control Package supports MSML Audit
   Conference Package as specified in section 10.2.

"msml-audit-conn": this Control Package supports MSML Audit
   Connection Package as specified in section 10.3.

"msml-audit-dialog": this Control Package supports MSML Audit Dialog
   Package as specified in section 10.4.

"msml-audit-stream": this Control Package supports MSML Audit Stream
   Package as specified in section 10.5.

so an application server using the Control Framework as its transport for MSML MUST use one or more package names, depending on what it needs from the media server ๐ŸŽฏ no vibes-based guessing here ๐Ÿ˜ค the package name(s) show up in the "Control-Packages" SIP header that's in the SIP INVITE dialog request which creates the control channel, as specified in [i11] ๐Ÿ’Œ

and last but not least, the "Control-Packages" value MAY be re-negotiated using the SIP re-INVITE mechanism ๐Ÿ”„ flexible energy, periodt ๐Ÿ’…โœจ

3.2.2. Control Framework Messages

okay so the way CONTROL, response, and REPORT messages from [i11] get used is different for every single Control Package in MSML ๐Ÿ’… so each one gets its own little section below โœจ

MSML Core Package "msml" ๐ŸŽ€

The application server may send a CONTROL message with a body of MSML request using the following elements to the MS:

  • <msml>: the root element that may contain a list of child elements that request a specific operation. The child elements are defined in extended packages (e.g., "msml-conf" and "msml-dialog"). This element is also the root element that contains an MSML result and event.
  • <send>: sends an event to the specified recipient within the media server. Specific event types are defined within the extended packages.

The media server replies with a response message containing a MSML result using the following elements:

  • <result>: reports the results of an MSML transaction.

The media server MAY send the MSML event to the application server, in a REPORT or CONTROL message, using the element <event>. The actual content of the <event> and which Control Framework message to use are defined within the extended packages. ๐Ÿฆ‹

MSML Conference Core Package "msml-conf" ๐Ÿ 

This package extends the MSML Core Package to define a framework for creation, manipulation, and deletion of a conference. ๐ŸŽช

The AS can send a CONTROL message with a body of the MSML request that contains one or multiple conference-related commands to the MS. The MS then replies with a response message with a body of the MSML result to indicate whether or not the request has been fulfilled. ๐Ÿ’Œ

During the lifetime of a conference, whenever an event occurs, the media server MAY send CONTROL messages containing MSML events to notify the application server. The application server SHOULD reply with a response message with no MSML body to acknowledge the event has been received. ๐Ÿ””

This package does NOT use the REPORT message. ๐Ÿ™…โ€โ™€๏ธ

Dialog Core Package "msml-dialog" ๐Ÿ’ฌ

This package extends the MSML Core Package to define the structural framework and abstractions for MSML dialogs. ๐Ÿงฑ

The application server MAY send CONTROL messages containing a MSML request using the following elements:

  • <dialogstart>: instantiate an MSML media dialog on a connection or a conference.
  • <dialogend>: terminates an MSML dialog.
  • <send>: sends an event and an optional namelist to the dialog, dialog group, or dialog primitive.
  • <exit>: used by the dialog description language to cause the execution of the MSML dialog to terminate.

For the <dialogstart> command, the response message MUST contain an MSML result that indicates that the dialog has been started successfully. The MSML result MAY contain <dialogid> to return the dialog identifier, if the identifier was assigned by the media server. Subsequently, zero or more MSML events MAY be initiated by the media server in (update) REPORT messages to report information gathered during the dialog. Finally, an MSML event "msml.dialog.exit" SHOULD be generated in a (terminate) REPORT message when the dialog terminates (e.g., MSML execution of <exit>). โฏ๏ธ

For the <dialogend> and <send> commands, the response message contains the final MSML result that indicates that the request has either been fulfilled or rejected. โœ…

Dialog Base Package "msml-dialog-base" ๐Ÿง

This package extends the MSML Dialog Core Package to define a set of base functionality for MSML dialogs. The extension defines individual media primitives, including <play>, <dtmfgen>, <tonegen>, <record>, <dtmf> and <collect>, to be used as child element of <dialogstart>. This package does not change the framework message usage as defined by the MSML Dialog Core Package. ๐ŸŽต

Dialog Transform Package "msml-dialog-transform" ๐ŸŒ€

This package extends the MSML Dialog Core Package to define a set of transform primitives that works as filter on half-duplex media streams. The extension defines transform primitives, including <vad>, <gain>, <agc>, <gate>, <clamp> and <relay>, that MAY be used as child elements of <dialogstart>. This package does not change the framework message usage as defined by the MSML Dialog Core Package. ๐ŸŽš๏ธ

Dialog Group Package "msml-dialog-group" ๐Ÿซ‚

This package extends the MSML Dialog Core, Base, and Transform Packages to define a single control flow construct that specifies concurrent execution of multiple media primitives. The extension defines the <group> element that MAY be used as a child element of <dialogstart> to enclose multiple media primitives, such that they can be executed concurrently. This package does not change the framework message usage as defined by the MSML Dialog Core Package. ๐Ÿ‘ฏโ€โ™€๏ธ

Dialog Speech Package "msml-dialog-speech" ๐Ÿ—ฃ๏ธ

This package extends the MSML Dialog Core and MSML Base Package to define functionality that MAY be used for automatic speech recognition and text to speech. The extension extends the <dialogstart> and the <play> elements.

For <dialogstart>, it defines a new child element <speech> to activate grammars or user input rules associated with speech recognition. For <play>, it defines a new child element <tts> to initiate the text-to-speech service.

This package does not change the framework message usage as defined by the MSML Dialog Core Package. ๐Ÿค–

Dialog Fax Detection Package "msml-dialog-fax-detect" ๐Ÿ“ 

This package extends the MSML Dialog Core Package to define primitives provide fax detection service. The extension defines a primitive <faxdetect> to be used as a child element of <dialogstart>. This package does not change the framework message usage as defined by the MSML Dialog Core Package. ๐Ÿ”

Dialog Fax Send/Receive Package "msml-dialog-fax-sendrecv" ๐Ÿ“จ

This package extends the MSML Dialog Core Package to define primitives that allow a media server to provide fax send or receive service. The extension defines new primitives <faxsend> and <faxrcv>, to be used as a child element of <dialogstart>. This package does not change the framework message usage as defined by the MSML Dialog Core Package. ๐Ÿ“ฌ

Dialog Audit Core Package "msml-audit" ๐Ÿ•ต๏ธโ€โ™€๏ธ

This package extends the MSML Core Package to define a framework for auditing media resource(s) allocated on the media server. ๐Ÿงพ

This package follows a simple request/response transaction, allowing the application server to send CONTROL messages containing MSML <audit> requests. The media server MUST reply with a response message containing the result. The result is contained within the <auditresult> element, returning the queried state information. ๐Ÿ“‹

This package does NOT use the REPORT message. ๐Ÿ™…โ€โ™€๏ธ

Dialog Audit Conference Package "msml-audit-conf" ๐ŸŽค

This package extends the MSML Audit Core Package to define conference specific states that MAY be queried via the <audit> command and the corresponding response MUST be returned by the <auditresult> element. This package does not change the framework message usage as defined by the MSML Audit Core Package. ๐Ÿ“Š

Dialog Audit Connection Package "msml-audit-conn" ๐Ÿ”Œ

This package extends the MSML Audit Core Package to define connection specific states that MAY be queried via the <audit> command and the corresponding response MUST be returned by the <auditresult> element. This package does not change the framework message usage as defined by the MSML Audit Core Package. ๐Ÿ“ก

Dialog Audit Dialog Package "msml-audit-dialog" ๐Ÿ’ญ

This package extends the MSML Audit Core Package to define dialog specific states that MAY be queried via the <audit> command and the corresponding response MUST be returned by the <auditresult> element. This package does not change the framework message usage as defined by the MSML Audit Core Package. ๐Ÿ—‚๏ธ

Dialog Audit Stream Package "msml-audit-stream" ๐ŸŒŠ

This package extends the MSML Audit Core Package to define stream specific states that MAY be queried via the <audit> command and the corresponding response MUST returned by the <auditresult> element. This package does not change the framework message usage as defined by the MSML Audit Core Package. ๐Ÿ’ง

3.2.3. Common XML Support

The XML schema described in [i11] MUST be supported by all Control Packages defined by MSML. However, the "connection-id" value MUST be constructed as defined by MSML (i.e., the identifier MUST contain a local dialog tag only, while the SIP Control Framework [i11] requires that the "connection-id" contain both local and remote dialog tags). ๐Ÿงฉ

3.2.4. Control Message Body

A valid CONTROL body message MUST conform to the MSML schema, as included in this specification, for the MSML package(s) used. ๐Ÿ“ฆ

3.2.5. REPORT Message Body

A valid REPORT body message MUST conform to the MSML schema, as included in this specification, for the MSML package(s) used. ๐Ÿ“

4. Language Structure โœจ

4.1. Package Scheme โœจ

okay so the big way MSML gets extended is the "package" ๐ŸŽ€ A package is a bundle of one or more XML schemas that add new features by using new or extended elements and attributes. Every package except the ones in this document lives in its own standards doc, like an Internet Draft or an RFC. Any package that extends base MSML MUST include references to the MSML base set of schemas from the Internet Drafts. A schema in a package MUST only extend MSML, meaning it must not change the existing spec. no touching the original ๐Ÿ™…โ€โ™€๏ธ

A given MSML script will reference all the schemas for the packages whose stuff it actually uses. A script MUST reference the MSML base and optionally any extension package(s). see the IANA Considerations section ๐Ÿ“‹

Each package MUST define its own namespace so that elements or attributes with the same name in different packages don't clash ๐Ÿ’… And if a script uses an element or attribute that lives in a package (instead of the base), it MUST prefix that name with the namespace name. it's giving organized ๐Ÿ—‚๏ธ

MSML is built from a core package that gives you the structure without any specific features. Extra packages sit on top of the core and add the functional stuff. You can mix any combination of extra packages with the core. The diagram below shows the MSML packages defined in this document ๐Ÿฆ‹

        +--------------------------------------------------------+
        |                     MSML Core                          |
        +--------------------------------------------------------+
              /                           \                 \
          +--------+                   +--------+        +-------+
          | Dialog |                   | Conf   |        | Audit |
          | Core   |                   | Core   |        | Core  |
          +--------+                   +--------+        +-------+
     ________  \_______________________________________      |
     ------------------------------------------------        |
    /         \          \         \          \      \       |
+------+  +---------+ +------+ +------+ +------+ +-------+   |
|Dialog|  |Dialog   | |Dialog| |Dialog| |Dialog| |Dialog |   |
|Base  |  |Transform| |Group | |Speech| |Fax   | |Fax    |   |
+------+  +---------+ +------+ +------+ |Detect| |Send/  |   |
                                        +------+ |Receive|   |
                                                 +-------+   |
                                     ________________________|
                                     -------------------------
                                    /       \       \         \
                                +-----+ +-----+ +------+ +------+
                                |Audit| |Audit| |Audit | |Audit |
                                |Conf | |Conn | |Dialog| |Stream|
                                +-----+ +-----+ +------+ +------+
  • MSML Core Package (Mandatory) ๐Ÿ’œ

This describes the minimum base framework that MUST be implemented to support additional core packages. non-negotiable bestie ๐Ÿ‘‘

  • MSML Conference Core Package (Conditionally Mandatory, for Conferencing) ๐ŸŽค

This describes the audio and multimedia basic and advanced conferencing package. It MAY be implemented, so it's a vibe choice ๐ŸŒธ

  • MSML Dialog Core Package (Conditionally Mandatory, for Dialogs) ๐Ÿ’ฌ

This describes the dialog core package, which MUST be implemented for any dialog services. However, systems that only do conferencing MAY omit support for MSML dialogs. The MSML Dialog Core Package is the framework that the other dialog packages plug into. The MSML Dialog Base Package MUST be supported, while all the other dialog packages MAY be supported.

  • MSML Dialog Base Package (Conditionally Mandatory, for Dialogs)
  • MSML Dialog Group Package (Optional)
  • MSML Dialog Transform Package (Optional)
  • MSML Dialog Fax Detection Package (Optional)
  • MSML Dialog Fax Send/Receive Package (Optional)
  • MSML Dialog Speech Package (Optional)
  • MSML Audit Core Package (Conditionally Mandatory, for Auditing) ๐Ÿ”

This describes the audit core package, which MUST be implemented to support auditing services. It's the framework the additional audit packages are supported within.

  • MSML Audit Conference Package (Conditionally Mandatory, for Auditing Conference, Conference Dialog, and Conference Stream)
  • MSML Audit Connection Package (Conditionally Mandatory, for Auditing Connection, Connection Dialog, and Connection Stream)
  • MSML Audit Dialog Package (Conditionally Mandatory, for Auditing Dialog, and MUST be used with either MSML Audit Conference Package or MSML Audit Connection Package)
  • MSML Audit Stream Package (Conditionally Mandatory, for Auditing Stream, and MUST be used with either MSML Audit Conference Package or MSML Audit Connection Package)

The formal way to extend MSML dialogs is to define a new package ๐Ÿง The new package MUST provide a text description of what extensions are included and how they work. It MUST also define an XML schema file (if applicable) that defines the new package, which can be done through extension, restriction of an existing package, or a specific profile of an existing package. Dependencies on other packages MUST be stated. For example, a package that extends or restricts another one depends on the original package's spec. Finally, the new package MUST be assigned a unique name and version. receipts please ๐Ÿ“

Here are the types of things you can define in new packages โœจ

  • new primitives
  • extensions to existing primitives (events, shadow variables, attributes, content)
  • new recognition grammars for existing primitives
  • new markup languages for speech generation
  • languages for specifying a topology schema
  • new predefined topology schemas
  • new variables / segment types (sets & languages)
  • new control flow elements

MSML packages get assembled into a specific MSML profile that different implementations can share ๐Ÿค The base MSML dialog profiles defined in this document are made up of the MSML Core Package, MSML Dialog Core Package, MSML Dialog Base Package, MSML Dialog Group Package, MSML Transform Package, MSML Fax Packages, and the MSML Speech Package.

MSML extension packages that define primitives MUST define the following for each primitive within the package:

  • the function that the primitive performs
  • the attributes that may be used to tailor its behavior
  • the events that it is capable of understanding
  • the shadow variables that provide access to information determined as a result of the primitive's operation

The mechanism for making sure a media server and its client share a compatible set of packages is not defined here ๐Ÿ™ˆ For now, the expectation is that provisioning will be used, possibly alongside a future auditing capability. Also, when used in SIP networks, packages could be defined using feature tags, and the procedures for Indicating User Agent Capabilities in SIP [i1] could be used to let a media server describe its capabilities to other user agents. it's a whole vibe ๐Ÿ’ซ


4.2. Profile Scheme ๐Ÿฆ‹

Not every device or app using MSML needs the entire MSML schema ๐Ÿ’… For example, a media processing device might only support audio announcements, only audio simple conferencing, or only multimedia IVR. It's highly desirable to have a system that describes exactly what portion of MSML a particular media processing device or control agent supports.

The package scheme we just talked about lets MSML functionality be grouped into packages that rely on the MSML core package. It lets a portion of the full MSML spec be implemented on a per-package basis, and it also sets up a framework for future extension packages. But inside a given package, sometimes only a subset of the package's functionality is needed. To support subsets of packages at a finer granularity than the package level, a profile scheme is required ๐ŸŽ€

MSML package profiles identify a subset of a given MSML package with specific definitions of elements and attributes. Each MSML package profile MUST be accompanied by one or more corresponding schemas. Using the examples above, there could be an audio announcements profile of the MSML Dialog Base Package, an audio simple conferencing profile of the MSML Conference Core Package, and a multimedia IVR profile of the MSML Dialog Base Package. so many possibilities ๐ŸŒˆ

MSML package profiles MUST be published separately from the MSML specification, in one or more standards documents (e.g., Internet Drafts or RFCs) dedicated to MSML package profiles. Profiles would not be registered with IANA, and any organization is additionally free to create its own profile(s) if it needs to. no gatekeeping here, we love a creator ๐Ÿซถ

5. Execution Flow ๐Ÿ”ฅ

okay so MSML runs on a model where there's one single control context inside a media server ๐Ÿงš. That context can have one or many SIP [n1] dialogs attached to it ๐Ÿ’œ. It's assumed that any SIP dialogs tied to the MSML control context were already authorized, as appropriate, by mechanisms outside the scope of MSML ๐Ÿซถ. Not MSML's job, bestie ๐Ÿ’….

The control context keeps track of the state of all the media objects and media streams inside the media server โœจ. It receives and processes every MSML request from authorized SIP dialogs, and it grabs every event that media objects generate internally and sends it out on the right SIP dialog ๐Ÿ“ฎ. An MSML request can create brand new media objects and streams, and it can modify or destroy any existing ones ๐Ÿฆ‹.

A single MSML request can be just one action for the media server to handle, in which case it's giving very simple command request energy ๐ŸŽ€. But honestly, it's often more natural for a client to ask for several actions at once, or to want a few actions tightly coordinated by the media server ๐Ÿ‘‘. Multiple MSML elements received in a single request MUST be processed sequentially in document order ๐Ÿ“‹.

An example of the first situation is creating a conference and joining it with an initial participant ๐ŸŒธ. An example of the second is unjoining one or more participants from a main conference and joining them to a sidebar conference ๐Ÿ“. In the first case, network latency may not be a big deal, but it's just simpler for the client to combine the requests ๐Ÿ’–. In the second case, the extra network latency between separate requests could mean the participant hears audio loss, and that is NOT it ๐Ÿ˜ญ.

Each MSML request is processed as a single transaction ๐ŸŽ€. A media server MUST ensure that it has the necessary resources available to carry out the complete transaction before executing any elements of the request ๐Ÿ”. If it doesn't have enough resources, it MUST return a 520 response and MUST NOT execute the transaction ๐Ÿšซ.

The MSML request MUST be checked for well-formedness and validated against the schema before any elements get executed ๐Ÿ“. This lets XML [n2] errors get reported right away, and it cuts down on failures in the middle of a transaction, which would otherwise leave only part of it executed ๐Ÿ™ˆ.

Each element is expected to execute immediately โšก. Elements such as <dialogstart>, which take an unpredictable amount of time, are "forked" and executed in a separate thread (see MSML Dialog Packages) ๐Ÿงต. Once they're successfully forked, execution just carries on with the element after the </dialogstart> โœจ. So MSML doesn't give you mechanisms to sequence or coordinate other operations with dialog elements ๐Ÿ™ƒ.

Processing within a transaction MUST stop if any errors occur ๐Ÿ›‘. Elements that were already executed before the error are NOT rolled back, so they stay done ๐Ÿ˜ฌ. It's the client's responsibility to decide what to do next based on the results in the response ๐Ÿง . Most elements MAY contain an optional "mark" attribute ๐Ÿ”–. The value of that attribute from the last successfully executed element MUST be returned in an error response ๐Ÿ“. Also, errors that happen during the execution of a dialog occur outside the context of an MSML transaction, so those get reported in an asynchronous event ๐Ÿ“ฃ.

Transaction results come back as part of the SIP request response ๐Ÿ’Œ. They show whether the transaction succeeded or failed ๐Ÿ’ฏ. The result MUST also include identifiers for any objects the media server created for which the client didn't provide an instance name ๐Ÿ†”. And if the transaction fails, the reason for the failure MUST be returned, and an indication of how much of the transaction was executed before the failure occurred SHOULD be returned too ๐Ÿ“Š. Iconic behavior, honestly ๐Ÿ‘‘.


6. Media Server Object Model ๐Ÿฆ‹

Media servers are general-purpose platforms for running real-time media processing tasks ๐ŸŒˆ. Those tasks range from simple stuff, like playing announcements, to seriously complex stuff, like speech interfaces, centralized multimedia conferencing, and sophisticated gaming applications ๐ŸŽฎ.

Calls get set up on a media server using SIP ๐Ÿ“ž. Clients will often use SIP third party call control (3PCC) [i4] to set up calls to a media server on behalf of end users ๐Ÿซถ. MSML doesn't require 3PCC, though. It only needs the client and the media server to share a common identifier for the call and its associated RTP [i3] sessions ๐Ÿ”—.

Objects are the entities that source, sink, or modify media streams ๐ŸŽ€. A media stream is a bidirectional or unidirectional media flow between objects on a media server ๐ŸŒŠ. The subsections below define the classes of objects that exist on a media server and how they're identified in MSML ๐Ÿงš.

6.1. Objects ๐Ÿ’–

A media object is an endpoint of one or more media streams ๐ŸŽฏ. It can be a connection that terminates RTP sessions coming in from the network, or a resource that transforms or manipulates media ๐Ÿ› ๏ธ. MSML defines four classes of media objects, and each class defines the basic properties of how object instances are used within a media server ๐Ÿญ. Most classes, though, need the client to define what specific instances actually do, using MSML or other languages such as VoiceXML ๐Ÿ“œ.

These are the classes of media processing objects that are defined. The class names are in parentheses ๐Ÿ’…:

  • network connection (conn)
  • conference (conf)
  • dialog (dialog)

A network connection is an abstraction for the media processing resources involved in terminating the RTP session(s) of a call ๐Ÿ“ก. For audio services, a connection instance presents a full-duplex audio stream interface within a media server ๐ŸŽง. Multimedia connections have multiple media streams of different media types, and each one corresponds to an RTP session ๐ŸŽฌ. Network connections get instantiated through SIP [n1] ๐Ÿ’ซ.

A conference represents the media resources and state information needed for a single logical mix of each media type in the conference (e.g., audio and video) ๐ŸŽค. MSML models multiple mixes or views of the same media type as separate conferences ๐Ÿชž. Each conference has multiple inputs, and those inputs can be divided into classes so an application can request different media treatment for different participants ๐Ÿ’œ. For example, the video streams for some participants might be assigned to fixed regions of the screen, while the ones for other participants only show up when they're speaking ๐ŸŽฅ.

A conference has a single logical output per media type ๐Ÿ“บ. For each participant, that output is the audio conference mix, minus any audio that participant contributed, plus the video mix shared by all conference participants ๐ŸŒท. Video conferences using voice activated switching have an optional ability to show the previous speaker to the current speaker ๐Ÿ™Œ.

Conferences are instantiated using the <createconference> element ๐Ÿ—๏ธ. The content of the <createconference> element specifies the parameters of the audio and/or video mixes ๐Ÿงพ.

Dialogs are a class of objects that represent automated participants ๐Ÿค–. They're similar to network connections from a media flow perspective, and they may have one or more media streams as the abstraction for their interface within a media server ๐ŸŒ€. The difference is that dialogs are created and destroyed through MSML, and the media server itself implements the dialog participant ๐Ÿช„. Dialogs are instantiated through the <dialogstart> element ๐Ÿš€. The contents of the <dialogstart> element define the desired or expected dialog behavior ๐Ÿ“‹. Dialogs can also be invoked by referencing VoiceXML as the dialog description language ๐ŸŽ™๏ธ.

Operators are functions used to filter or transform a media stream ๐ŸŽš๏ธ. The function an operator instance fulfills is defined as a property of the media stream ๐Ÿงฉ. Operators may be unidirectional or bidirectional, and they have a media type ๐ŸŽจ. Unidirectional operators reflect simple atomic functions, like automatic gain control, filtering tones out of conferences, or applying specific gain values to a stream ๐Ÿ”Š. They have a single media input, connected to the media stream from one object, and a single media output, connected to the media stream of a different object ๐Ÿ”€.

Bidirectional operators have two media inputs and two media outputs ๐Ÿ‘ฏ. One input and output is associated with the stream to one object, and the other input and output is associated with a stream to a different object ๐Ÿ’ž. Bidirectional objects may treat the media differently in each direction ๐Ÿ™ƒ. For example, an operator could change the media sent to a connection based on speech it recognized, or on dual-tone multi-frequency (DTMF) it received from that connection ๐Ÿ“ž. Operators are implicitly instantiated when streams are created or modified using the elements <join> and <modifystream>, respectively ๐Ÿง .

The relationships between the different object classes (conf, conn, and dialog) are shown in the figure below ๐Ÿ–ผ๏ธ.

           +--------------------------------------+
           |           Media Server               |
           |                                      |
           |------+                      ,---.    |
           |      |      +------+       /     \   |
<== RTP ==>| conn |<---->| oper |<---->( conf  )  |
           |      |      +------+       \     /   |
           |------+                      `---'    |
           |   ^                           ^      |
           |   |                           |      |
           |   |   +------+    +------+    |      |
           |   |   |      |    |      |    |      |
           |   +-->|dialog|    |dialog|<---+      |
           |       |      |    |      |           |
           |       +------+    +------+           |
           +--------------------------------------+

A single, full-duplex instance of each object class is shown, along with the common relationships between them ๐Ÿงฉ. An operator (such as gain) sits between a connection and a conference, and dialogs are shown participating both with an individual connection and with a conference ๐ŸŽ€. The figure isn't meant to imply only one-to-one relationships ๐Ÿ™…. Conferences will often have hundreds of participants, and either connections or conferences may be interacting with more than one dialog ๐Ÿฅณ. For example, one dialog might be recording a conference while other dialogs announce participants joining or leaving it ๐ŸŽ™๏ธโœจ.

6.2. Identifiers ๐Ÿฆ‹

okay bestie, so objects get referenced with identifiers made of one or more terms ๐Ÿ’… Each term says what kind of object it is (the object class) and which one specific object it means (the instance). The two get split by a colon : inside the term.

Identifiers get handed out the moment an object is first created โœจ The MSML client or the media server can both pick the instance name. If the client doesn't pick one, the media server picks it for them ๐ŸŽ€ Whatever name the server picks gets sent back to the client as a complete object identifier in the response to the request that made the object.

Some objects are totally fine existing on their own ๐ŸŒธ Connections can be created through SIP at any time, and then MSML can link their media to other objects to build services. Conferences can be created with specific resources reserved, just waiting for participants to connect ๐Ÿงš

So connections and conferences are independent objects because they can exist on a standalone basis. Their identifiers are just a single term, like conf:abc or conn:1234. If a client picks its own instance names for independent objects, it must use globally unique instance names ๐ŸŒˆ One way to get that is to put the client's domain name into the name.

Dialogs exist to provide a service to independent objects ๐Ÿ’– They can act as a participant in a conference, or interact with a connection kinda like a two-participant call. Dialogs depend on independent objects existing, and that shows up in how their identifiers are built. Operators change the media flow between other objects, like adding gain between a connection and a conference. Since operators are just media transform primitives defined as properties of the media stream, they don't get identifiers and are created implicitly โœจ

Dialog identifiers are a list of terms separated by slashes (/). The left-most term has to specify a conference or a connection, and that becomes the root. Here's an example of a dialog acting as a conference participant:

conf:abc/dialog:recorder

All objects except connections are created using MSML ๐Ÿ’… Connections are created when media sessions get established through SIP. There are a few options that clients and media servers can use to set up a shared instance name for a connection and its media streams.

When media servers support multiple media types, the instance name SHOULD be a call identifier that can be used to identify the collection of RTP sessions associated with a call ๐Ÿฆ‹ When MSML is used together with SIP and third party call control, the call identifier MUST be the same as the local tag the media server assigned to identify the SIP dialog. That's the tag the media server adds to the "To" header in its response to an initial INVITE transaction. RFC 3261 requires those tag values to be globally unique ๐Ÿ˜ญ

Here's an example of a connection identifier: conn:74jgd63956ts.

With third party call control, the MSML client acts as a back-to-back user agent (B2BUA) to set up the media sessions ๐Ÿซถ SIP dialogs get established between the client and the media server, which lets the media server's local tag be used as a connection identifier. If third party call control isn't used, a SIP event package MAY be used so a media server can tell a subscribed client about new sessions ๐Ÿ’œ

Identifiers let every object on a media server be uniquely addressed, but they can also point at multiple objects at once โœจ Right now there are two ways to do that:

  • wildcards
  • common instance names

An identifier can reference multiple objects when a wildcard is used as an instance name. MSML reserves the instance name made of a single asterisk (*) to mean all objects that share the same identifier root and class ๐Ÿ‘‘ Instance names containing an asterisk cannot be created. Wildcards MUST only be used as the right-most term of an identifier, and they MUST NOT be used as part of the root for dialog identifiers ๐Ÿ™ˆ Wildcards are only allowed where explicitly indicated below.

These are valid wildcards:

conf:abc/dialog:*
conn:*

And this is illegal wildcard usage:

conf:*/dialog:73849

Even though identifiers share a common syntax, MSML elements restrict which classes of objects are valid in a given context ๐Ÿ’€ For example, it's valid to join two connections together, but it's not valid to join two IVR dialogs. Not me trying to join two IVR dialogs ๐Ÿ˜ญ

7. MSML Core Package โœจ

This section describes the core MSML package, which MUST be supported in order to use any other MSML packages ๐Ÿ’– The core package is basically a framework with no explicit functionality of its own. Functional packages get used on top of it ๐ŸŽ€

7.1. <msml> ๐ŸŒธ

<msml> is the root element. When a media server receives it, it defines the set of operations that make up a single MSML request ๐Ÿงš Operations are requested by what's inside the element. Each operation MAY appear zero or more times as a child of <msml>. Specific operations are defined in the conference package and in the set of dialog packages ๐Ÿฆ‹

The results of a request, or the contents of events a media server sends, are also wrapped in the <msml> element โœจ The results of the transaction go in as a body in the response to the SIP request that carried the transaction. That response contains any identifiers the media server assigned to newly created objects. Every message a media server generates is correlated to an object identifier. Objects and identifiers are covered in section 6 (Media Server Object Model) ๐Ÿ’…

Attributes:

  • version: "1.1" Mandatory

7.2. <send> ๐Ÿ’…

Events are used to affect how different objects behave inside a media server ๐Ÿ”ฅ The <send> element sends an event to a specified recipient within the media server.

Attributes:

  • event: the name of an event. Mandatory.
  • target: an object identifier. When the identifier is for a dialog, it may optionally be appended with a slash "/" followed by the target to be included in an MSML dialog <send>. Mandatory.
  • valuelist: a list of zero or more parameters that are included with the event.
  • mark: a token that can be used to identify execution progress in the case of errors. The value of the mark attribute from the last successfully executed MSML element is returned in an error response. Therefore, the value of all mark attributes within an MSML document should be unique ๐Ÿ“

7.3. <result> ๐ŸŽ€

The <result> element reports the results of an MSML transaction ๐Ÿซถ It's included as a body in the final response to the SIP request that started the transaction. An optional child element <description> can include text that explains what error responses mean ๐Ÿ˜ญ Response codes are defined in section 11 (Response Codes).

Attributes:

  • response: a numeric code showing the overall success or failure of the transaction, and for a failure, the reason why. Mandatory.
  • mark: in the case of an error, the value of the mark attribute from the last successfully executed element that included the mark attribute.

If something fails, a description of the reason SHOULD be given using the child element <description> โœจ

Three other child elements let the response include identifiers for objects that the request created but that didn't have instance names specified by the client ๐ŸŒˆ Those elements are <confid> and <dialogid>, for objects created through a <createconference> and <dialogstart> respectively.

7.4. <event> ๐Ÿงš

The <event> element is how a media server notifies an event to a media server client ๐Ÿ”ฅ The MSML Core Package defines three types of events: "msml.dialog.exit", "msml.conf.nomedia", and "msml.conf.asn". These correspond to a dialog terminating, a conference being automatically deleted when the last participant leaves, and the notification of the current set of active speakers for a conference, in that order ๐Ÿ’œ Events can also be generated by an executing dialog. In that case, the event type is specified by the dialog (see MSML Dialog Core Package <send>).

Attributes:

  • name: the type of event. If the event is generated because of the execution of an MSML dialog <send>, the value MUST be the value of the "event" attribute from the <send> element within the MSML Dialog Core Package. If the event is generated because of the execution of an <exit>, the value MUST be "moml.exit". If the event is generated because of the execution of a <disconnect>, the value MUST be "moml.disconnect". If the event is generated because of an error, the value must be "moml.error". Mandatory.
  • id: the identifier of the conference or dialog that generated the event or caused the event to be generated. Mandatory.

<event> has two children, <name> and <value>, which hold the name and value respectively of each namelist item associated with the event ๐ŸŽ€

8. MSML Conference Core Package ๐Ÿ‘‘

8.1. Conferences ๐ŸŒธ

A conference has a mixer for each type of media it supports ๐Ÿ’– Each mix has a matching description that defines how the media from participants contributes to that mix. A mixer has multiple inputs that get combined in a media-specific way to create a single logical output ๐Ÿฆ‹

The elements that describe the mix for each media type are called mixer description elements. They are:

<audiomix> defines the parameters for mixing audio media.

<videolayout> defines the composition of a video window.

Those elements, defined in sections 8.6 (Audio Mix) and 8.7 (Video Layout) respectively, get used as content of the <createconference> element to set up a conference's initial properties โœจ They get used inside the <modifyconference> element to change a conference's properties once it's been created, or inside the <destroyconference> element to remove individual mixes from the conference ๐Ÿ’…

Conferences can be terminated by an MSML client, either by using the <destroyconference> element to remove the entire conference or by removing the last mixer(s) associated with it ๐Ÿ™ˆ A media server can also terminate conferences automatically, based on criteria specified when the conference was created. When the conference gets deleted, any remaining participants will have their associated SIP dialogs either left unchanged or deleted, depending on the value of the "term" attribute specified when the conference was created ๐Ÿซถ

8.2. Media Streams โœจ

okay bestie, so every object has at least one media input and one media output for each type of media it supports ๐ŸŽ€ each object class is the one that decides how many input and output objects of that class it supports ๐Ÿ’… media streams get created when objects are joined, either explicitly with <join> or implicitly when dialogs are created with <dialogstart> ๐Ÿฆ‹ dialog creation happens in two stages: first the resources for the dialog instance get allocated and configured, and then those resources get implicitly joined to the dialog target while the dialog is running ๐Ÿงš for the full scoop, check out the MSML Dialog Base Package ๐Ÿ“š

a join operation creates a bidirectional audio stream between two objects by default ๐ŸŽง video and unidirectional streams can also be created ๐ŸŒˆ a media stream is made by connecting the output of one object to the input of another object, and then the other way around too (assuming it's a bidirectional or full-duplex join) ๐Ÿ’–

many objects can only take a single input for each type of media ๐Ÿซถ in this specification, only the conference object class can take an arbitrary number of inputs ๐Ÿ‘‘ so if a stream gets requested to an object that already has a stream of the same type plugged into its single input, the result depends on what kind of media stream it is ๐Ÿค”

audio mixing works by summing audio signals ๐ŸŽถ and automatically mixing audio streams is super useful! like, you can bridge two streams to make a simple three-way call, or bridge a private announcement with a (whispered) conference mix for one participant ๐Ÿคซ for general conferences though, an MSML client SHOULD create an audio conference and then join participants to it ๐ŸŒธ and conference mixers SHOULD subtract each participant's audio from the mix so they don't hear themselves ๐Ÿ™ˆ

when a media server gets a request to join an audio stream to the single audio input of an object that already has an audio stream connected, it SHOULD automatically bridge the new stream with the existing one, making a mix of the two audio streams โœจ how many streams can be bridged this way is implementation specific ๐Ÿ“ it is RECOMMENDED that a media server support bridging at least two streams ๐Ÿ’œ and a media server that cannot bridge a new stream with any existing streams MUST fail the operation requesting the join ๐Ÿ’€

video is a whole different vibe ๐ŸŽฌ there are lots of ways two video streams can be combined and shown, like side by side in separate panes, picture in picture, or one pane showing only one stream at a time based on something like active speaker ๐Ÿ“บ each option makes a very different presentation and needs really different media resources, so automatic bridging of video is not supported ๐Ÿ™…โ€โ™€๏ธ a media server MUST fail requests to join a new video stream to an object that only supports a single video input and already has a video stream connected to that input ๐Ÿ˜ญ if you want an object to have multiple video streams joined to it, the object itself has to be capable of supporting multiple video streams ๐ŸŽ€ conference objects can support multiple video streams and give you a way to specify the mixing presentation for them ๐Ÿฆ‹

a media server MUST NOT establish any streams unless it can create all the streams requested by an operation ๐Ÿšซ streams can only be created if both objects support a media type and at least one of these conditions is true:

  1. Each object that is to receive media is not already receiving a stream of that type.
  2. Any object that is to receive media and is already receiving a stream of that type supports receiving an additional stream of that type. The only class of objects defined in this specification that directly support receiving multiple streams of the same type are conferences.
  3. The media server is able to automatically bridge media streams for an object that is to receive media and that is already receiving a stream of the requested type. The only type of media defined in this specification that MAY be automatically bridged is audio.

the directionality of media streams on a connection is modeled separately from what SDP [n9] allows for the matching RTP [i3] sessions ๐ŸŽ€ media servers MUST respect the SDP in what they actually transmit, but they MUST NOT let the SDP change the directionality when joining streams inside the media server ๐Ÿ’…


8.3. <createconference> ๐ŸŽช

<createconference> is used to allocate and configure the media mixing resources for conferences ๐ŸŽช the properties for each type of media mix the conference needs get described inside the content of the <createconference> element ๐Ÿง mixer descriptions are covered in the Audio Mix and Video Layout sections ๐ŸŽต when no mixer descriptions are specified, the default behavior MUST be equivalent to including a single <audiomix> ๐Ÿซถ

clients can ask a media server to automatically delete a conference when a specified condition happens, using the "deletewhen" attribute ๐Ÿ—‘๏ธ a value of "nomedia" means the conference MUST be deleted when no participants are left, and when that happens, an "msml.conf.nomedia" event MUST be notified to the MSML client ๐Ÿ‘€ a value of "nocontrol" means the conference MUST be deleted when the SIP [n1] dialog carrying the <createconference> element gets terminated, and when that happens, a media server MUST terminate all participant dialogs by sending a BYE for their associated SIP dialog ๐Ÿ’€ and a value of "never" MUST leave the ability to delete a conference under the control of the MSML client ๐Ÿฆ‹

Attributes:

  • name: the instance name of the conference. If the attribute is not present, the media server MUST assign a globally unique name for the conference. If the attribute is present but the name is already in use, an error (432) will result and MSML document execution MUST stop. Events that the conference generates use this name as the value of their "id" attribute (see section 7.4 (<event>)). ๐Ÿท๏ธ
  • deletewhen: defines whether a media server should automatically delete the conference. Possible values are "nomedia", "nocontrol", and "never". Default is "nomedia". ๐Ÿ—‘๏ธ
  • term: when true, the media server MUST send a BYE request on all SIP dialogs still associated with the conference when the conference is deleted. Setting term equal to false lets clients start dialogs on connections once the conference has completed. Default is "true". ๐ŸŽฌ
  • mark: a token that MAY be used to identify execution progress in the case of errors. The value of the mark attribute from the last successfully executed MSML element is returned in an error response. Therefore, the value of all mark attributes within an MSML document should be unique. ๐Ÿ”–

here's an example of creating an audio conference ๐ŸŽค this conference lets at most two participants contend to be heard, and it reports the set of active speakers no more frequently than every 10 seconds โฐ

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <createconference name="example">
      <audiomix>
         <n-loudest n="3"/>
         <asn ri="10s"/>
      </audiomix>
   </createconference>
</msml>

8.3.1. <reserve> ๐Ÿ›Ž๏ธ

conference resources can be reserved by including the <reserve> element as a child of <createconference> ๐Ÿ’ผ <reserve> lets you specify a set of resources that a media server will reserve for the conference โœจ any requests for resources beyond those that have been reserved should be honored on a best-effort basis by a media server ๐ŸŒŸ

Attributes:

  • required: boolean that specifies whether <createconference> should fail if the requested resources are not available. When set to false, the conference will be created, with no reserved resources, if the complete reservation cannot be honored. Default is "true". ๐Ÿฅบ

8.3.1.1. <resource> ๐Ÿงฉ

the resources to be reserved are defined using <resource> ๐Ÿ“ฆ the contents of these elements describe a resource to be reserved ๐ŸŽ€ descriptions are implementation dependent ๐Ÿคทโ€โ™€๏ธ media servers that support MSML dialogs may use the elements from that package as the basis for resource descriptions ๐Ÿ’… each resource element may use the attribute "n" to define the quantity of the resource to reserve ๐Ÿ”ข

Attributes:

  • n: number of resources to be reserved. Default is 1. ๐Ÿ”ข
  • type: specifies whether the resource is to be reserved by each individual participant or reserved as a shared conference resource. Valid values for this attribute are "individual" or "shared". Default is "individual". ๐Ÿ™‹โ€โ™€๏ธ

for example, the following creates a conference and reserves two types of resources ๐Ÿซง one resource element can represent resources shared by all participants of the conference, while the other can represent resources reserved for each of the expected participants ๐Ÿ’–

<createconference>
   <reserve>
      <resource n="20">
        <!--description of resources used by each participant-->
      </resource>
      <resource n="2" type="shared">
        <!--description of the shared conference resources-->
      </resource>
   </reserve>
</createconference>

8.4. <modifyconference> ๐ŸŽ€

okay bestie, so โœจ every property of an audio mix or the presentation of a video mix can be changed while the conference is alive, using <modifyconference> ๐Ÿ’–. audio mix changes go in an <audiomix> child of <modifyconference>, and that same move can add an audio mixer if there wasn't one yet ๐Ÿ”ฅ. video presentation changes go in a <videolayout> child, and it works the same way for adding a video mixer if none was allocated before ๐Ÿฆ‹

mixers get removed by putting a mixer description element inside <destroyconference/> ๐Ÿ’…

features and presentation aspects get enabled, added, or modified by including the element(s) that define them inside a mixer description ๐Ÿซถ. you have to include the complete specification of the element, just like you would when the conference gets created. the new definition completely replaces any previous definition, so no leftovers ๐Ÿ’€. only the stuff defined by elements in the mixer descriptions gets affected. any existing configuration aspects of a conference that you don't specify in <modifyconference/> MUST maintain their current state in the media server ๐Ÿ‘‘

for example, if an MSML client wanted to change the minimum reporting interval for active speaker notification from the one shown in the Conference Examples section (<createconference>), it would send this to the media server:

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <modifyconference id="conf:example">
      <audiomix>
         <asn ri="4"/>
      </audiomix>
   </modifyconference>
</msml>

this would also turn on active speaker notification if it wasn't already enabled ๐ŸŽ€. the N-loudest mixing is unaffected ๐Ÿ’œ

multiple elements MAY be included in the mixer descriptions, similar to when conferences are created ๐Ÿงš. like, in a video conference, the video mix description (<videolayout>) could say the layout should change so the regions currently showing participants get smaller, and new region(s) get created to support more participants. it's giving main character energy ๐Ÿ˜ญ. a media server MUST make all of the requested changes or none of the requested changes ๐Ÿ”ฅ

more examples of modifying conferences are in the Conference Examples section ๐ŸŒˆ

Attributes:

  • id: the identifier for a conference. Wildcards MUST NOT be used. Mandatory.
  • mark: a token that can be used to identify execution progress in the case of errors. The value of the mark attribute from the last successfully executed MSML element is returned in an error response. Therefore, the value of all "mark" attributes within an MSML document SHOULD be unique. ๐Ÿ“

8.5. <destroyconference> ๐Ÿ’€

<destroyconference> is used to delete mixers, or to delete the entire conference and all of its state and shared resources ๐Ÿซง. when a mixer is removed, all of the streams joined to that mixer get unjoined. when a conference is destroyed, SIP dialogs for any remaining participants MUST be maintained or removed based on the value of the "term" attribute when the conference was created ๐Ÿ‘‘

when there's no element content, <destroyconference/> deletes the entire conference ๐Ÿ’…. individual mixers get removed by including a mixer description element that identifies the mix (or mixes) to be removed as content of <destroyconference/>. <audiomix/> is used to remove audio mixers, and <videolayout/> is used to remove video mixers ๐Ÿฆ‹. when one or more mixer descriptions are specified, the media server MUST only delete the specified mixer and MUST NOT affect any other existing mixers ๐Ÿ”ฅ. when <audiomix/> or <videolayout/> is identified for individual removal, other feature aspects of the mix MUST NOT be included. if they are specified anyway, the media server MUST ignore those elements ๐Ÿ™ˆ. when the last mixer is removed from a conference, a media server MUST remove all conference state, leaving or removing any remaining SIP dialogs as described above ๐ŸŒธ

Attributes:

  • id: the identifier for a conference. Mandatory.
  • mark: a token that can be used to identify execution progress in the case of errors. The value of the mark attribute from the last successfully executed MSML element is returned in an error response. Therefore, the value of all "mark" attributes within an MSML document SHOULD be unique. ๐Ÿ“

8.6. <audiomix> ๐ŸŽค

the properties of the overall audio mix are specified using the <audiomix> element โœจ

Attributes:

  • id: an optional identifier for the audio mix.
  • samplerate: an integer value that specifies the sample rate (in Hz) for the audio mixer. Optional, default value of 8000. ๐Ÿ’œ

an example of the description for an audio mix looks like this:

<audiomix id="mix1">
  <asn ri="10s"/>
  <n-loudest n="3"/>
</audiomix>

8.6.1. <n-loudest> ๐Ÿ”Š

the <n-loudest> element says that participants contend to be included in the conference mix based on their audio energy ๐Ÿ†. when the element is not present, all participants are mixed ๐Ÿซถ

Attributes:

  • n: the number of participants that will be included in the audio mix based on having the greatest audio energy. Mandatory.

8.6.2. <asn> ๐Ÿ‘€

the <asn> element enables notification of active speakers ๐Ÿ—ฃ๏ธ. active speakers MUST be notified using the <event> element with an event name of msml.conf.asn. the namelist of the event consists of the set of active speakers, and the name of each item is the string speaker, with a value of the connection identifier for that connection ๐Ÿ’–

Attributes:

  • ri: the minimum reporting interval defines the minimum duration of time that must pass before changes to active speakers will be reported. A value of zero disables active speaker notification. ๐Ÿ™…โ€โ™€๏ธ
  • asth: specifies the active speaker threshold (in units of dBm0). Valid value range is 0 to -96. Optional, default is -96. ๐ŸŽš๏ธ

an example of an active speaker notification looks like this:

<event name="msml.conf.asn" id="conf:example">
   <name>speaker</name>
   <value>conn:hd93tg5hdf</value>
   <name>speaker</name>
   <value>conn:w8cn59vei7</value>
   <name>speaker</name>
   <value>conn:p78fnh6sek47fg</value> </event>

8.7. <videolayout> ๐Ÿ“บ

a video layout is specified using the <videolayout> element ๐ŸŽฌ. it's used as a container to hold the elements that describe all of the properties of a video mix. the parameters of the window that displays the video mix are defined by the <root> element ๐ŸชŸ. when the video mix is composed of multiple panes, the location and characteristics of those panes are defined by one or more <region> elements. a <region> element is not required when only a single video stream is displayed at one time and none of the visual attributes of regions are required ๐Ÿงš

some regions may display a video stream based on selection criteria, instead of continuously showing one participant's stream ๐ŸŽ“. one example is a distance learning lecture, where the instructor sees each of the students periodically displayed in a region. when a region is used to display one of a number of streams, it is placed as a child of a <selector> element ๐Ÿ’…

Attributes:

  • type: specifies the language used to define the layout. Layouts defined using MSML MUST use the value text/msml-basic-layout. This is the same convention as defined for the layout package from the W3C SMIL 2.0 specification [i6]. The default when omitted is text/msml-basic-layout. ๐Ÿ“œ
  • id: an optional identifier for the video layout. ๐Ÿ†”

8.7.1. <root> ๐ŸชŸ

the <root> element describes the root window, or virtual screen, that the conference video mix will be displayed in ๐ŸŒˆ. simple conferences can display participant video directly within the root window, but more complex conferences will use regions for this purpose. areas of the window that aren't used to display video will show the root window background ๐Ÿ–ผ๏ธ

all video presentations require a root window. it MUST be present when a video mix is created, and it cannot be deleted; however, its attributes MAY be changed using the <modifyconference> element ๐Ÿ”’โœจ

Attributes:

  • size: the size of the root window, specified as one of the five standard common intermediate formats (e.g., CIF, QCIF). ๐Ÿ“
  • backgroundcolor: the color for the root window background, defined using the values for the "background-color" property of the CSS2 specification [n10]. ๐ŸŽจ
  • backgroundimage: the URI for an image to be displayed as the root window background. Transparent portions of the image allow the background color to show through. ๐ŸŒ…

8.7.2. <region> ๐ŸŽ€

Okay bestie, <region> elements are the video panes that show participant video streams ๐Ÿ“บโœจ. They always get rendered on top of the root window ๐ŸชŸ.

The size of a region is set relative to the root window with the relativesize attribute ๐Ÿ“. Those sizes are fractions, like 1/4 or 1/3, which keep the aspect ratio of the original video and make scaling way more efficient ๐Ÿ’….

Regions get placed on the root window with the position attributes top and left ๐Ÿ“. They mark the top left corner of the region as an offset from the top left corner of the root window. You can give them as a number of pixels, or as a percent of the vertical or horizontal dimension of the root window. Percent values end with a percent (%) character. 33% and 67% should be read as 1/3 and 2/3, which makes it super easy to line regions up with sizes that are relative to the root window ๐Ÿงฉ.

Here's an example of a video layout with six regions ๐ŸŒˆ:

    +-------+---+
    |       | 2 |
    |   1   +---+
    |       | 3 |
    +---+---+---+
    | 6 | 5 | 4 |
    +---+---+---+
   <videolayout type="text/msml-basic-layout">
      <root size="CIF"/>
      <region id="1" left="0" top="0" relativesize="2/3"/>
      <region id="2" left="67%" top="0" relativesize="1/3"/>
      <region id="3" left="67%" top="33%" relativesize="1/3">
      <region id="4" left="67%" top="67%" relativesize="1/3"/>
      <region id="5" left="33%" top="67%" relativesize="1/3"/>
      <region id="6" left="0" top="67%" relativesize="1/3"/>
   </videolayout>

Which part of the root window a region covers depends on its position and its size ๐Ÿ—บ๏ธ. When regions overlap, they stack up by their priority attribute ๐Ÿฅž. The region with the highest priority value sits below all the others and gets hidden by anything overlapping it ๐Ÿซฅ. The region with the lowest non-zero priority value sits on top of everything and never gets hidden by overlaps ๐Ÿ‘‘. priority takes values between 0 and 1. A value of zero disables the region, frees up any resources tied to it, and unjoins any video stream that was showing in it ๐Ÿšซ.

Regions that don't set a priority get one from the media server when the conference is created ๐Ÿค–. The first region inside the <videolayout> element without a priority gets a priority of one, the second gets two, and so on. So every region that doesn't set a priority ends up underneath every region that does ๐Ÿ›๏ธ. Among the no-priority regions, they stack from top to bottom in the order they show up inside <videolayout> ๐Ÿ“š.

For example, say a layout looks like this:

   <videolayout>
      <root size="CIF"/>
      <region id="a" ... priority=".3" .../>
      <region id="b" ... />
      <region id="c" ... priority=".2" ...>
      <region id="d" ... />
   </videolayout>

Then the layering goes, from top to bottom: c, a, b, d ๐Ÿฅฐ.

Anything of a region that hangs off the edge of the root window gets cropped โœ‚๏ธ. For example, this layout:

   <videolayout>
      <root size="CIF"/>
      <region id="foo" left="50%" top="50%" relativesize="2/3"/>
   </videolayout>

would look roughly like this:

   +-----------+
   |   root    |
   |background |
   |     +-----+--
   |     |     |//
   |     | foo |//
   +-----+-----+//
         |////////

Visual attributes are how you style the look of individual regions ๐ŸŽจ. You can add a border, plus a title and/or a logo. Text and logos show up as images on top of the region's video, and they sit below every region with a lower priority ๐Ÿ’–. The visual attributes are title, titletextcolor, titlebackgroundcolor, bordercolor, borderwidth, and logo ๐Ÿฆ‹.

Visual attributes can also be set on individual streams (Video Stream Properties) ๐ŸŽž๏ธ. When both a region and a stream set visual attributes, the stream ones MUST take precedence ๐Ÿ”ฅ. That way, streams that get picked for display automatically (Stream Selection) still get their proper text and logos ๐Ÿซถ. The region's visual attributes only appear when no stream is linked to that region ๐ŸŒธ.

Two more attributes on a region, blank and freeze, control the state of the video shown in it ๐ŸงŠ. When blank or freeze is set to "true", the media server MUST display the region either as a blank region, or with the video image frozen on the last frame it received ๐Ÿฅถ.

These two attributes live on regions and aren't allowed on streams, because that seems to be the common use case ๐Ÿ’…. If you applied them to streams, only that one stream would be affected inside a selector while the others kept displaying normally ๐Ÿ™ƒ. Outside of personal mixing scenarios, you can get the same result by having the participant mute their own transmission to the media server ๐Ÿคซ.

Here are the attributes for each region ๐Ÿ“:

  • id: a name that can be used to refer to the region ๐Ÿท๏ธ.
  • left: the position of the region from the left side of the root window โฌ…๏ธ.
  • top: the position of the region from the top of the root window โฌ†๏ธ.
  • relativesize: the size of the region, expressed as a fraction of the root window size ๐Ÿ“.
  • priority: a number between 0 and 1 that sets the precedence when rendering overlapping regions. A value of zero disables the region ๐Ÿฅ‡.
  • title: text to be displayed as the title for the region ๐Ÿ“ฐ.
  • titletextcolor: the color of the text ๐ŸŒท.
  • titlebackgroundcolor: the color of the text background ๐ŸŽจ.
  • bordercolor: the color of the region border ๐Ÿ–๏ธ.
  • borderwidth: the width of the region border ๐Ÿ“.
  • logo: the URI of an image file to be displayed ๐Ÿ–ผ๏ธ.
  • freeze: a boolean value, with a default of "false", that defines whether the video image should be frozen at the currently displayed frame ๐ŸงŠ.
  • blank: a boolean value, with a default of "false", that defines whether the region should display black instead of the associated video stream ๐Ÿ–ค.

8.7.3. <selector> ๐Ÿ’…

It's really common to want one of several video streams picked automatically for display ๐ŸŽฏ. The <selector> element defines the selection criteria and its parameters ๐Ÿ“‹. The selection algorithm is set by the method attribute ๐Ÿง . The selection methods defined right now let you do voice activated switching, or step through the associated video streams one at a time ๐Ÿ”.

The regions that will display the selected video stream go inside the <selector> element as child elements ๐Ÿช†. Putting regions inside a <selector> doesn't change how they're laid out next to regions that aren't part of the selection ๐Ÿงญ. For simple video conferences that show video right in the root window, you can nest the <root> element as a child of <selector> ๐ŸŒŸ. Region elements MUST NOT be used in that case ๐Ÿ™…โ€โ™€๏ธ.

For example, here's a super common layout where the active speaker's video shows in the big region ("1") at the top left, while five other participants are in regions around the edge ๐ŸŽค๐Ÿ’œ:

   +-------+---+
   |       | 2 |
   |   1   +---+
   |       | 3 |
   +---+---+---+
   | 6 | 5 | 4 |
   +---+---+---+
   <videolayout type="text/msml-basic-layout">
      <root size="CIF"/>
      <selector id="switch" method="vas">
         <region id="1" left="0" top="0" relativesize="2/3"/>
      </selector>
      <region id="2" left="67%" top="0" relativesize="1/3"/>
      <region id="3" left="67%" top="33%" relativesize="1/3">
      <region id="4" left="67%" top="67%" relativesize="1/3"/>
      <region id="5" left="33%" top="67%" relativesize="1/3"/>
      <region id="6" left="0" top="67%" relativesize="1/3"/>
   </videolayout>

Every selector method has to be defined so that it still works when there's only one region as its child ๐Ÿซง. Selector methods that handle more than one child region MUST specify how they work across those multiple regions ๐Ÿงฉ. Media server implementations MAY support only a single region for methods that are defined to allow multiple regions ๐Ÿค.

A participant's video gets its selector or region through the display attribute of <stream>, used during a join operation ๐Ÿšช. Picking a selector means the stream gets shown according to that selector's method ๐ŸŽฌ. Picking a region supports continuous presence display of participants ๐Ÿ‘ฏ. Some streams can be joined with both a selector and a region ๐Ÿ’ซ. In that case, the <blankothers> attribute decides whether the streams tied to a continuous presence region should get blanked when that stream is selected for display in one of the selector regions ๐Ÿ™ˆ.

These attributes are common to all selector methods ๐Ÿ“:

  • id: a name that can be used to refer to the selector ๐Ÿท๏ธ.
  • method: the name of the method used to select the video stream. A value of "vas" (see the following section, Voice Activated Switching) MAY be specified ๐ŸŽ™๏ธ.
  • status: specifies whether the selector is "active" or "disabled" ๐ŸŸข.
  • blankothers: when "true", video streams that are also displayed in continuous presence regions will have those continuous presence regions blanked when the stream is displayed in a selection region ๐Ÿซฃ.

8.7.3.1. Voice Activated Switching ("vas") ๐Ÿฆ‹

Voice activated switching (VAS) shows the video stream that matches the participant who's speaking right now ๐Ÿ—ฃ๏ธโœจ. You specify it with a selector method value of "vas" ๐Ÿ’œ.

If the active speaker's video isn't currently showing in a selection region, it replaces the video in whichever region is showing the speaker who was least recently active ๐Ÿ”„. If the active speaker's video is already showing in a selection region, nothing changes at all ๐Ÿ™Œ. When VAS is applied to a single region, the current speaker just ends up displayed in that region ๐Ÿ‘‘.

Attributes:

  • si: switching interval, which is the minimum period of time that must elapse before the video is allowed to switch to the active speaker โณ.
  • speakersees: defines whether the active speaker sees the "current" speaker (themselves) or the "previous" speaker ๐Ÿ‘€.

8.8. <join> ๐Ÿ”—

okay so <join> is the element that creates one or more streams between two independent objects ๐Ÿ’… streams can be audio or video, and they can be bidirectional or unidirectional. a bidirectional stream is basically two unidirectional streams glued together, and you can tweak each one on its own ๐Ÿซถ the streams you want get specified by <stream> elements (section <stream>) as the content of <join> โœจ

no content at all? then <join> defaults to a bidirectional audio stream ๐ŸŽง so if you've only got one type of stream between two objects, or you've only got a unidirectional stream, you can use <join> to add another media type or make the stream bidirectional by including the right <stream> elements. to turn a bidirectional stream into a unidirectional one, use <unjoin> (section <unjoin>) to remove the direction you don't need anymore ๐Ÿฆ‹

<stream> elements also set the properties of a stream, like gain, voice masking, or tone clamping for audio, or labels and other visual stuff for video ๐ŸŒธ properties are often set asymmetrically, meaning one direction only. if one direction should behave differently from the other, you need two <stream> elements inside the <join>, one for each direction, when you're creating a bidirectional stream ๐Ÿ’œ

If a media server can provide services using both compressed or uncompressed media, the MSML client may need to distinguish within requests which format is to be used. When compressed streams are created, both objects must use the same media format or an error response (450) is generated.

Attributes:

  • id1: an identifier of either a connection or conference. Wildcards MUST NOT be used. Mandatory. Any other object class results in a 440 error. ๐Ÿ™…โ€โ™€๏ธ
  • id2: an identifier of either a connection or conference. Wildcards MUST NOT be used. Mandatory. Any other object class results in a 440 error.
  • mark: a token that can be used to identify execution progress in the case of errors. The value of the mark attribute from the last successfully executed MSML element is returned in an error response. So the value of all mark attributes within an MSML document SHOULD be unique. ๐Ÿท๏ธ

okay now the fun part, a call center coaching scenario ๐ŸŽ€ a supervisor can listen to the convo between an agent and a customer and drop hints to the agent, and the customer can't hear those hints. one join sets up a stream between the agent and the customer, another sets up a stream between the agent and the supervisor, and a third join makes a half-duplex stream from the customer to the supervisor. the media server automatically bridges the media streams from the customer and the supervisor for the agent, and from the customer and the agent for the supervisor. iconic teamwork ๐Ÿ‘‘

assuming these connections, each with a single audio stream:

conn:supervisor

conn:agent

conn:customer

this is how you create the media flows we just talked about:

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <join id1="conn:supervisor" id2="conn:agent"/>
   <join id1="conn:agent" id2="conn:customer"/>
   <join id1="conn:supervisor" id2="conn:customer">
      <stream media="audio" dir="to-id1"/>
   </join>
</msml>

here's joining a participant to a multimedia conference ๐Ÿ“บ it assumes the conference has a video presentation region named "topright". the "display" attribute is explained in the section Video Stream Properties.

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <join id1="conn:hd83t5hf7g3" id2="conf:example">
      <stream media="audio"/>
      <stream media="video" dir="from-id1" display="topright"/>
      <stream media="video" dir="to-id1"/>
   </join>
</msml>

8.9. <modifystream> ๐Ÿช„

media streams can have different properties, like the gain on an audio stream or a visual label on a video stream ๐ŸŽฌ these properties get specified as the content of <stream> elements (section <stream>). <modifystream> is how you change the properties of a stream: you include one or more <stream> elements that should have their properties changed.

okay this part is important ๐Ÿšจ stream properties MUST be set as specified by the <stream> element used as a child of the <modifystream> element. any properties you leave out of the <stream> element when modifying a stream MUST remain unchanged. setting a property for only one direction of a bidirectional stream MUST NOT affect the other direction. if you want to change the directionality of streams, issue an <unjoin> followed by a <join>. any streams between the two objects that aren't included within <modifystream> MUST NOT be affected ๐Ÿ™Œ

Attributes:

  • id1: an identifier of either a conference or a connection. The instance name MUST NOT contain a wildcard if "id2" contains a wildcard. Mandatory.
  • id2: an identifier of either a conference or a connection. The instance name MUST NOT contain a wildcard if "id1" contains a wildcard. Mandatory.
  • mark: a token that can be used to identify execution progress in the case of errors. The value of the mark attribute from the last successfully executed MSML element is returned in an error response. So the value of all mark attributes within an MSML document is RECOMMENDED to be unique. ๐Ÿท๏ธ

8.10. <unjoin> ๐Ÿงน

<unjoin> removes one or more media streams between two objects. if there's no content in the <stream> element, then all media streams between the objects MUST be removed ๐Ÿ’€ you can remove individual streams by specifying them with <stream> elements, and the streams you didn't specify MUST NOT be removed. to change a bidirectional stream into a unidirectional one, unjoin the direction you no longer need using the <unjoin> element. operator elements MUST NOT be specified within <stream> elements when you're unjoining streams with the <unjoin> element. any stream operators that do get specified MUST be ignored ๐Ÿซ 

<unjoin> and <join> can be used together to move a media stream, like from a main conference to a sidebar conference ๐Ÿงš

Attributes:

  • id1: an identifier of either a conference or a connection. The instance name MUST NOT contain a wildcard if "id2" contains a wildcard. Mandatory.
  • id2: an identifier of either a conference or a connection. The instance name MUST NOT contain a wildcard if "id1" contains a wildcard. Mandatory.
  • mark: a token that can be used to identify execution progress in the case of errors. The value of the mark attribute from the last successfully executed MSML element is returned in an error response. So the value of all mark attributes within an MSML document SHOULD be unique. ๐Ÿท๏ธ

this example removes a participant from a conference and plays a leave tone for everyone still in it ๐Ÿ””

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <unjoin id1="conn:jd73ht89sf489f" id2="conf:1"/>
   <dialogstart target="conf:1" type="application/moml+xml">
      <play>
         <audio uri="file://leave_tone.wav"/>
      </play>
   </dialogstart>
</msml>

8.11. <monitor> ๐Ÿ‘€

<monitor> is a specialized unidirectional join that copies the media destined for a connection object. one use for <monitor> is quality monitoring within a conference ๐Ÿ“Š the media stream can be removed using the <unjoin> element (see the section <unjoin>).

Attributes:

  • id1: an identifier of the connection to be monitored. Mandatory. Any other object class results in a 440 error. Wildcards MUST NOT be used. ๐Ÿ™…โ€โ™€๏ธ
  • id2: an identifier of the object that is to receive the copy of the media destined to id1. id2 may be a connection or a conference. Mandatory. Any other object class results in a 440 error. Wildcards MUST NOT be used.
  • compressed: "true" or "false". Specifies whether the join should occur before or after compression. When "true", id2 must be a connection using the same media format as id1 or an error response (450) is generated. Default is "false".
  • mark: a token that can be used to identify execution progress in the case of errors. The value of the mark attribute from the last successfully executed MSML element is returned in an error response. So the value of all mark attributes within an MSML document SHOULD be unique. ๐Ÿท๏ธ

8.12. <stream> ๐ŸŽถ

individual streams get specified using the <stream> element ๐ŸŽต it MAY be included as a child element in any of the stream manipulation elements <join>, <modifystream>, or <unjoin>.

the type of stream is set with a "media" attribute, using values that match the top-level MIME media types defined in RFC 2046 [i7]. this specification only covers audio and video media. other specifications may define procedures for additional types ๐ŸŽž๏ธ

a stream is bidirectional when there's no direction attribute "dir" present. a stream is unidirectional when a direction attribute is present. the "dir" attribute MUST have a value of "from-id1" or "to-id1", depending on the direction you need. these values are relative to the identifier attributes of the parent element ๐Ÿงญ

the compressed attribute tells you whether the stream is compressed, when that matters ๐Ÿ—œ๏ธ what happens when the attribute isn't present is implementation specific. joining compressed streams acts much like an RTP [i3] relay.

the properties of media streams get specified as the content of <stream> elements when the element is a child of <join> or <modifystream>. <stream> elements MUST NOT have any content when they're used as a child of <unjoin> to identify specific streams to remove ๐Ÿšซ

some properties are defined in MSML as extra attributes or child elements of <stream> that are specific to the media type. the ones for audio streams and video streams are defined in the following two sub-sections. operators, which you can think of as properties of the media stream, MAY be specified as child elements of the <stream> element โœจ

Attributes:

  • media: "audio" or video". Mandatory
  • dir: "from-id1" or "to-id1".
  • compressed: "true" or "false". Specifies whether the stream uses compressed media. Default is implementation specific.

8.12.1. Audio Stream Properties โœจ

Okay so audio mixes can be set up to only mix the N-loudest people ๐ŸŽค, but lowkey there are some "preferred" participants who should always get to talk. ๐Ÿ’– When audio streams join a conference that uses N-loudest audio mixing, you have to identify the preferred streams. ๐Ÿซถ

A preferred audio stream is identified with the "preferred" attribute. The "preferred" attribute MAY be used for an audio stream that is input to a conference and MUST NOT be used for other streams. ๐Ÿ’…

Additional attributes of the <stream> element for audio streams are:

Attributes:

  • preferred: a boolean value that defines whether the stream does not contend for N-loudest mixing. A value of "true" means that the stream MUST always be mixed while a value of "false" means that the stream MAY contend for mixing into a conference when N-loudest mixing is enabled. Default is "false". ๐Ÿ“

There are two elements that can be used to change the characteristics of an audio stream, as defined below. ๐ŸŽ€

8.12.1.1. <gain>

The <gain> element can be used to adjust the volume of an audio media stream. ๐Ÿ”Š You can set it to a specific gain amount, have it automatically adjust the gain to a target level, or mute the stream. ๐Ÿคซ

Attributes:

  • id: an optional identifier that may be referenced elsewhere for sending events to the gain primitive. ๐Ÿงš
  • amt: a specific gain to apply, specified in dB, or the string "mute", which indicates that the stream should be muted. This attribute MUST NOT be used if "agc" is present. ๐Ÿ™ˆ
  • agc: a boolean indicating whether automatic gain control is to be used. This attribute MUST NOT be used if "amt" is present. ๐Ÿ’œ
  • tgtlvl: the desired target level for AGC, specified in dBm0. This attribute MUST be specified if "agc" is set to "true". This attribute MUST NOT be specified if "agc" is not present. ๐ŸŒˆ
  • maxgain: the maximum gain that AGC may apply. Maxgain is specified in dB. This attribute MUST be used if "agc" is present and MUST NOT be used when "agc" is not present. ๐Ÿ‘‘

8.12.1.2. <clamp>

The <clamp> element is used to filter tones and/or audio-band DTMF from a media stream. ๐Ÿงน

Attributes:

  • dtmf: a boolean indicating whether DTMF tones should be removed. ๐Ÿ“ต
  • tone: a boolean indicating whether other tones should be removed. ๐Ÿ”‡

8.12.2. Video Stream Properties ๐ŸŽฌ

Video mixes define a presentation that may have multiple regions, such as a quad-split. ๐ŸชŸ Each region displays the video from one or more participants. When video streams are joined to such a conference, the region that will display the video needs to be specified as part of the join operation. ๐Ÿฆ‹

The region that will display the video is specified using the "display" attribute. The "display" attribute MUST be used for a video stream that is input to a conference and MUST NOT be used for other streams. The value of the attribute MUST identify a <region> (see the section <region>) or a <selector> (see the section <selector>) that is defined for the conference. A stream MUST NOT be directly joined to a region that is defined within a selector. ๐Ÿšซ Changing the value of the "display" attribute can be used to change where in a video presentation layout a video stream is displayed. ๐ŸŒธ

Additional attributes of the <stream> element for video streams are:

Attributes:

  • display: the identifier of a video layout region or selector that is to be used to display the video stream. ๐ŸŽž๏ธ
  • override: specifies whether or not the given video stream is the override source in the region defined by the "display" attribute. Valid values are "true" or "false". Optional, default value is "false". Only a video stream that is input to a conference can be the override source. A particular region can have at most one override source at a time. The most recently joined video stream with this attribute set to "true" becomes the override source. When there's an override source in place, its video is always displayed in the region, regardless of what video selection algorithm (either a selector or continuous presence mode) is configured for that region. Once the override source is cleared, the conference MUST revert back to the original video selection algorithm. ๐Ÿ‘‘๐Ÿ”ฅ

8.12.2.1. <visual>

Some regions of video conferences may display different streams automatically, such as when voice activated switching is used. ๐Ÿ—ฃ๏ธ Connections MAY also be joined directly without the use of video mixing. In these cases, the <visual> element may be used to define visual display properties for a stream. โœจ

The <visual> element MAY use any of the visual attributes defined for regions (see the section <region>). This allows the visual aspects of regions within a <selector> to be tailored to the selected video stream, or for streams that are directly joined to display a name or logo. ๐Ÿท๏ธ๐Ÿ’…

9. MSML Dialog Packages ๐Ÿงš

9.1. Overview

MSML Dialog Packages define an XML [n2] language for composing complex media objects from a vocabulary of simple media resource objects called primitives. ๐Ÿงฉ It is primarily a descriptive or declarative language for describing media processing objects. MSML dialogs operate on a single or multiple streams that are identified by the MSML document outside the scope of the MSML Dialog Package. ๐Ÿ“„

MSML dialogs are intended to be used in different environments. ๐ŸŒ As such, the language itself does not define how an MSML dialog is used. Each environment in which an MSML dialog is used must define how it is used, the set of services provided, and the mechanism for passing information between the environment and the MSML dialog. The specific mechanisms used to realize the interface between an MSML dialog and its environment are platform specific. ๐Ÿ› ๏ธ

MSML Dialog Packages provide two models for access to media resources and service creation building blocks. ๐Ÿ’œ Both models MAY be used in conjunction with each other in a complementary manner. The first model (referred to as "Media Primitives and Composites", part of the mandatory MSML Dialog Base Package) contains media primitives (such as digit collection and announcements) and composite functions (such as play and collect combined as a single operation). The second model (referred to as "Media Groups", part of the optional MSML Dialog Group Package) allows the ability to define complex customized interactions, via event passing mechanisms, between media primitives, if required. ๐ŸŽ€

      MSML Dialog Core Package

         Defines core framework over which all MSML Dialog Packages
         operate.

      MSML Dialog Base Package

         Media Primitives
            <dtmf> or <collect>
                        DTMF digit collection
            <play>
                        Playing of Announcements
            <dtmfgen>
                        Generation of DTMF digits
            <tonegen>
                        Tone genration
            <record>
                        Media recording

         Media Composites
            <collect>
                        Supports play and collect operation.
                        Composite function with inclusion of play.
            <record>
                        Supports play and record operation.
                        Composite function with inclusion of play.

      MSML Dialog Group Package
            <group>
                        Allows grouping of media primitives for parallel
                        execution, with an event exchange mechanism
                        between the media primitives to achieve
                        customized media operations. All the above media
                        primitive elements are accepted within the
                        group.

The following operations MUST be supported using the elements described above, using either the MSML Dialog Base Package or the MSML Dialog Group Package. ๐Ÿฌ

      Announcement only
                        <play>
            Collection only
                        <dtmf> or <collect>

            Recording only
                        <record>

            Play and Collect
                        <collect>
                           <play/>
                        </collect>

            Play and Record
                        <record>
                           <play/>
                        </record>

Additional MSML Dialog Packages are:

  • MSML Dialog Transform Package ๐Ÿ”„
  • MSML Dialog Speech Package ๐Ÿ—จ๏ธ
  • MSML Fax Detection Package ๐Ÿ“ 
  • MSML Fax Send/Receive Package ๐Ÿ“จ

MSML dialogs MAY be used to simply expose primitive media resource objects, but they will be used more often to describe dialog operations and media transformation objects that can be controlled via user interaction. ๐Ÿซถ

MSML dialogs do not contain any computation or flow control constructs. ๐Ÿ™…โ€โ™€๏ธ There are no results automatically generated when media operations complete. Results MUST be explicitly requested using a <send> or <exit> element within the definition of the MSML dialog. ๐Ÿ’€

9.2. Primitives ๐ŸŽ€

okay bestie, primitives are the little workers that each do ONE job on a media stream (or on a bunch of streams) โœจ like generating audio or video, recognizing speech or DTMF, or adjusting the gain ๐Ÿ”Š. You can compose them so they run concurrently, which is giving multitasking energy ๐Ÿ’…. Primitives that are not composed for concurrent execution MUST simply execute sequentially, in the order they show up in an MSML document. Anything running concurrently inside the same MSML object (the one defined in a single MSML document) MAY chat with each other through events (see MSML Dialog Group Package) ๐Ÿ’ฌ.

Primitives get sorted into these descriptive categories ๐Ÿ—‚๏ธ:

  • Recognizers have a media input but no output. They let you recognize or detect different things inside a media stream and generate events based on what they receive ๐Ÿ‘€.
  • Transformers have one media input and one output, and they may send and receive events ๐Ÿ”.
  • Sources and sinks generate or consume media. They have either a media input or a media output but not both. They may receive and generate events too ๐ŸŽค.
  • Composites combine underlying primitives to give higher-level user interaction, without needing specific event-based exchanges between those primitives. They're the simpler option for more common services, like play and collect or play and record ๐ŸŽ.

Primitives may define different media processing behavior (states) based on the events they receive ๐ŸŽญ. Primitives that support different processing states must define their default starting state and should support the "initial" attribute so that state can be specified when the primitive is instantiated ๐ŸŒธ. All primitives must support the "terminate" event class ๐Ÿ›‘.

The following types of primitives are defined in this specification ๐Ÿ“‹:

      Recognizers    Transformers   Source/Sink   Composites
      ------------------------------------------------------
       dtmf/collect   agc            play          dtmf/collect
       faxdetect      clamp          record        record
       speech         gain           dtmfgen
       vad            gate           tonegen
                      relay          faxsend
                                     faxrcv

Primitives have shadow variables, similar to the ones in VoiceXML [n5], and they get values assigned automatically whenever a primitive is used โœจ. When an MSML dialog context starts up, every shadow variable has the string value "undefined". Each primitive has its own set of shadow variables, and those are global in scope across the whole MSML dialog context ๐ŸŒ.

Names SHOULD be assigned to individual primitives when more than one primitive of the same type is used within one MSML document ๐Ÿท๏ธ. If a primitive hasn't been named and gets instantiated a second time, its shadow variables get overwritten ๐Ÿ˜ฌ.

Shadow variables cannot be modified under user control ๐Ÿ™…โ€โ™€๏ธ. They may be returned from the MSML dialog context using the <send> element ๐Ÿ“ค.


9.3. Events ๐Ÿ’Œ

Events are how primitives talk to each other, and how an MSML context talks to its outside world ๐Ÿ—ฃ๏ธ. That outside world is defined by the way the MSML context was invoked. This will often be through MSML, but other languages and protocols such as SIP may also be used ๐Ÿ“ž.

Every primitive and group conceptually implements its own event queue. Events sent to them get placed into their queue and are removed and processed in order ๐Ÿ“ฅ. Primitives within a group conceptually have their own thread of execution ๐Ÿงต. Since servicing events from multiple queues is asynchronous, you can't assume that several events sent in sequence to different queues will be processed in the order they were sent ๐Ÿ™ƒ. Say recognition led to events going to both a <play> and a <record>, in that order. The <record> could totally process its event before the <play> ๐Ÿ˜ณ.

Each primitive defines the set of events it supports and how it behaves when handling each one ๐ŸŽ›๏ธ. That means tons of behaviors can be defined. For example, VCR-style controls can be built by making primitives that support an event for each control, and media recognition or detection can be what triggers those events ๐Ÿ“ผ.

Events can also come from somewhere else, like a control agent, and just get received by the primitive that implements the control ๐Ÿ•น๏ธ. Examples include adjusting volume (gain) and pausing and resuming both announcement playout and record creation โฏ๏ธ.

Primitives act on events based on the longest match of an event name ๐Ÿ”. Event names are a period '.' delimited sequence of tokens. The first token, the root of the name, can be thought of as an event class ๐Ÿ›๏ธ. Matching lets a standard meaning be defined and then extended based on what triggers an event's generation. For example, a record primitive behaves differently depending on whether it completed because a user stopped speaking or because it was cancelled. The recording is kept in the first case but not the second ๐ŸŽ™๏ธ.

Longest match also means new recognizers can be created and used without changing how existing primitives are defined ๐Ÿง . For example, a face recognition capability could generate a terminate.frowning event when a user looks puzzled ๐Ÿคจ. No primitive directly defines that event, but it will still trigger a generic terminate action. Primitives that need specialized behavior for frowning can be extended to support it. The event can also be exported from the MSML context without requiring the primitives that receive it to understand facial expressions ๐Ÿซถ.


9.4. MSML Dialog Usage with SIP ๐Ÿ“ž

MSML dialogs MAY be used directly with SIP for dialog interactions (e.g., IVR or fax) ๐ŸŽง. They can be invoked initially as part of the "Prompt and Collect" service described in "Basic Network Media Services with SIP" [n7]. That defines service indicators for a small number of well-defined services, using the user part of the SIP Request-URI (R-URI) ๐Ÿ”‘.

The prompt and collect service uses "dialog" as its service indicator, and URI parameters further refine the specific IVR request ๐ŸŽ€. This document defines an additional parameter "msml-param" for the dialog service indicator, like this:

   dialog-parameters = ";" ( dialog-param [ vxml-parameters ] )
                           | moml-param
   dialog-param      = "voicexml=" dialog-url
   moml-param        = "moml=" moml-url

There are no additional URI parameters when MSML is used as the dialog language ๐Ÿ™Œ.

MSML dialogs define discrete IVR dialog commands ๐Ÿ“ฆ. These commands MAY be included directly in the body of the INVITE to the "dialog" service indicator by using the "cid" [n8] URL scheme. That scheme identifies a message body part, which in this case would contain the MSML dialog request ๐Ÿ’Œ. Note that a multipart message body containing a single part MUST be present, even if the INVITE does not contain an SDP offer โš ๏ธ. Subsequent MSML dialog requests are sent in the body of SIP INFO messages, same as all messages from a media server ๐Ÿ“จ.

An example of the SIP URI described above is:

      sip:dialog@mediaserver.example.net;\
          moml=cid:14864099865376@appserver.example.net

The body part that contained the MSML dialog referenced by the URL would have a Content-Id header of:

      Content-Id: <14864099865376@appserver.example.net>

The results of executing an <exit> or <disconnect>, or of executing a <send> whose "target" attribute value equals "source", are notified in SIP INFO messages using the <event> element from the MSML Core package ๐Ÿ””. No messages are sent if execution completes normally without executing one of these elements ๐Ÿคซ.

If there's an error during validation or execution, a media server MUST notify the error as described above, and it must include the namelist items moml.error.status and moml.error.description ๐Ÿšจ. The values for these items are defined in section 11 ๐Ÿ“š.

A restricted subset of MSML dialogs can also be used with the "Announcement" service defined in [n7] ๐Ÿ“ข. That service uses "annc" as its service indicator and defines parameters that describe an announcement. The "play=" parameter identifies the URL of a prompt or a provisioned announcement sequence. Its value can refer to an MSML dialog body part using a "cid" URL as described above. That body part must only contain the <play> primitive ๐ŸŽต.

Using MSML dialogs enhances the announcement service ๐Ÿ’–. The client can specify a sequence of audio segments instead of needing each sequence to be provisioned, and video is supported too ๐ŸŽฌ. Plus, MSML dialogs define a standard set of variables, whereas [n7] defines a parameterization mechanism but does not formally specify any semantics ๐Ÿค“.

If a media server does not understand the "cid" scheme, or does not understand MSML dialogs, it must respond with the SIP response code 488 - not acceptable here ๐Ÿ™…โ€โ™€๏ธ. If the MSML dialog body contains elements other than the <play> primitive, or there are errors during validation, a media server must respond with 400 - bad request ๐Ÿ’€. Finally, if there's a discrepancy between parameters specified in the Request-URI and the corresponding attributes defined in the MSML dialog body, the Request-URI parameters must be silently ignored ๐Ÿซฅ.

MSML dialogs MUST NOT change the operation of the announcement service from what's defined in [n7] ๐Ÿ™…โ€โ™€๏ธ. When the announcement completes, a media server issues a SIP BYE request ๐Ÿ‘‹. The INFO method MUST NOT used with the announcement service ๐Ÿšซ.


9.5. MSML Dialog Structure and Modularity ๐Ÿงฉ

MSML is structured as a set of packages, and only the core and base packages are required ๐Ÿ“ฆ. The Dialog Core Package defines the framework for MSML requests to a media server, without any specific functionality ๐Ÿฆด. It consists of the "primitive" abstraction, an abstract element for control flow, the sequential execution model, and the <send> element ๐Ÿ”ง. Basically, the MSML Dialog Core Package lets you execute a sequence of one or more media processing primitives, with the ability to notify events to the invocation environment ๐Ÿ””.

Primitives are contained within the MSML Dialog Base Package, which defines the basic <play>, <record>, <dtmf>, <dtmfgen>, <tonegen>, and <collect> elements ๐ŸŽ. Another package, the MSML Dialog Transform Package, defines the simple half-duplex filters ๐ŸŽš๏ธ. More advanced primitives are defined in the speech and fax packages ๐Ÿ—ฃ๏ธ. The MSML speech package depends on the MSML Dialog Base Package, since it extends <play> by adding synthesized speech ๐Ÿค–. Finally, the group execution model, which is currently the only element that changes the flow of control, is defined in a separate MSML Dialog Group Package ๐ŸŒˆ. All of these packages are optional, with one exception: the MSML Dialog Core and MSML Dialog Base Packages MUST be implemented to provide the minimal functionality ๐Ÿ’œ.

9.6. MSML Dialog Core Package โœจ

okay so the MSML Dialog Core Package is giving structure ๐ŸŽ€ It sets up the framework and abstractions for MSML dialogs (through its schema), and it also defines the basic elements that aren't part of the core primitive or control abstractions. This package depends on the MSML Core Package, so it's not doing this alone ๐Ÿซถ Events from dialogs, like prompt completion, digits collected, or dialog termination, get passed up by the media server through the MSML Core Package (see MSML Core Package <event>).

Dialogs run totally independently from the MSML core context ๐Ÿ’… When a dialog starts, MSML allocates the dialog control resources and, if that works, gets them running. The core keeps going without waiting for the dialog to finish. That fork from the core context happens through the <dialogstart> element. Media streams get created between the dialog target and other internal media server resources while the dialog runs. Stream creation has to follow the requirements in the MSML Core Package, plus the media stream rules in the MSML Conference Core Package. no cap, the rules are important ๐Ÿ”ฅ

9.6.1. <dialogstart> ๐Ÿงš

The <dialogstart> element starts an MSML media dialog on connections or conferences ๐Ÿฆ‹ The dialog can be inline or pulled in by a URI [n6]. Inline dialogs MUST be composed of any of the MSML Dialog Packages. MSML dialogs MAY be defined externally as VoiceXML [n5]. And if there's a src attribute holding a URI, the MSML dialog description MUST NOT be inline. that's a hard no ๐Ÿ™…โ€โ™€๏ธ

When the dialog finishes, the originator gets notified with a "msml.dialog.exit" event. Any results the dialog returns on exit get sent along as a namelist in that event ๐Ÿ’œ

The "msml.dialog.exit" event also fires when a dialog fails. That can happen if there's an error fetching an external document, or an error inside the dialog's execution thread. In that case the event carries a namelist with the items "dialog.exit.status" and "dialog.exit.description", so the client knows what went wrong and why. The values for those items are defined in this package and in the MSML Core Package. Any info from the failed dialog can come back as extra namelist items too.

Attributes:

  • target: an identifier of a connection or a conference that will interact with the dialog. The identifier must not contain wildcards. Mandatory. ๐ŸŽฏ
  • src: the URL of the dialog description. MUST NOT be used if the MSML dialog description is inline. Otherwise, an error (422) will result and MSML document execution will stop. ๐Ÿšซ
  • type: a MIME type that identifies the type of language used to describe the dialog. application/moml+xml and application/vxml+xml are used to identify MSML dialogs and VoiceXML [n5] respectively. Mandatory. ๐Ÿท๏ธ
  • name: an instance name for the dialog. If the attribute isn't there, the media server assigns an identifier to the dialog. If the attribute is present but the name is already linked to the target, an error (431) will result and MSML document execution will stop. Any results the dialog generates get correlated to its identifier. ๐Ÿซง
  • mark: a token that helps identify execution progress when errors happen. The mark value from the last successfully executed MSML element comes back in an error response. So all mark attributes in an MSML document should be unique. ๐Ÿ”–

Here are some examples, because you know I love a good example ๐ŸŒธ First, starting an external MSML dialog on a connection:

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <dialogstart target="conn:abcd1234"
         type="application/moml+xml"
         name="sample"
         src="http://server.example.com/scripts/foo.moml"/>
 </msml>

Next, an inline embedded MSML dialog on a connection:

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
  <dialogstart target="conn:abcd1234" name="sample">
     <play>
        <audio uri="file://clip1.wav"/>
        <audio uri="http://host1/clip2.wav"/>
        <tts uri="http://host2/text.ssml"/>
        <var type="date" subtype="mdy" value="20030601"/>
     </play>
     <send target="source"
            event="done"
            namelist="play.amt play.end"/>
   </dialogstart>
</msml>

And last, a VoiceXML dialog started on a connection:

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <dialogstart target="conn:abcd1234"
       type="application/vxml+xml"
       name="sample"
       src="http://server.example.com/scripts/foo.vxml"/>
</msml>

If that dialog fails after its execution thread has started (say the VoiceXML document fetch fails), the event coming back looks like this ๐Ÿ˜ญ

<?xml version="1.0" encoding="UTF-8"?>
<event name="msml.dialog.exit"
       id="conn:abcd1234/dialog:sample">
   <name>dialog.exit.status</name>
   <value>423</value>
   <name>dialog.exit.description</name>
   <value>External document fetch error</value>
</event>

9.6.2. <dialogend> ๐Ÿ’€

<dialogend> is how you terminate an MSML dialog that was created with <dialogstart> before it finishes on its own ๐Ÿ™ˆ How it works depends on the dialog language the executing context is using. For VoiceXML, a "connection.disconnected" event gets thrown to the VoiceXML application. For MSML dialog, a "terminate" event gets sent to the MSML core context.

<dialogend> gives the running dialog a chance to wrap up gracefully before it generates a "msml.dialog.exit" event. Dialog results can still come back, packed in a namelist on that event โœจ

Attributes:

  • id: the identifier of a dialog. Mandatory. ๐Ÿชช
  • mark: a token that helps identify execution progress when errors happen. The mark value from the last successfully executed MSML dialog element comes back in an error response. So all mark attributes in an MSML document should be unique. ๐Ÿ”–

For example, if the dialog from the previous example were still running, this would end it and generate an "msml.dialog.exit" event:

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <dialogend id="conn:abcd1234/dialog:sample"/>
</msml>

9.6.3. <send> ๐Ÿ“จ

The <send> element sends an event, plus an optional namelist, to the recipient named in the target attribute. Event names are defined by the recipient. When the recipient is an MSML dialog group or primitive, the events are defined in this document. Other recipients MAY use names that suit their environment ๐ŸŒˆ

The target attribute says who gets the event. Recipients MAY be other MSML dialog primitives or groups running inside the object, the object itself, or the environment that invoked the MSML dialog. Sending events to media primitives or groups is supported by the MSML Dialog Group Package. Any target that's unknown inside the object is assumed to belong to the external environment. By convention, the string "source" SHOULD used to address that environment, but any target name that's different from the MSML dialog namespace MAY be used ๐Ÿฆ‹

Attributes:

  • event: the name of an event. Mandatory. ๐Ÿ“ฃ
  • target: the recipient of the event. The recipient MUST be an MSML dialog primitive, the currently executing group, or the MSML dialog environment. A primitive is specified by a primitive type, optionally followed by a period '.' and the identifier of a primitive. Identifiers are only needed when more than one primitive of the same type exists in the object. The executing group is specified with the token "group". The environment is specified with the token "source", optionally followed by a period '.' and any environment-specific target. Mandatory. ๐ŸŽฏ
  • namelist: a list of zero or more shadow variables that are included with the event. ๐Ÿงพ

9.6.4. <exit> ๐Ÿ‘‹

The <exit> element makes the MSML dialog stop executing ๐Ÿฅ€

Attributes:

  • namelist: a list of one or more shadow variables that MAY optionally be sent to the context that invoked the MSML Dialog object. ๐ŸŽ

9.6.5. <disconnect> ๐Ÿ”Œ

The <disconnect> element is like <exit>, but it has an extra meaning: it tells the context that invoked the MSML dialog to disconnect from a media server, along with the media stream tied to the object. How the disconnect happens depends on how the media stream was first set up. If SIP was used, a <disconnect> makes a media server issue a BYE request. That request gets sent for the SIP dialog attached to the media session the MSML dialog was running on ๐Ÿ“ž

Attributes:

  • namelist: a list of one or more shadow variables that MAY optionally be sent to the context that invoked the MSML dialog object. ๐ŸŽ€

9.7. MSML Dialog Base Package ๐ŸŒท

The MSML Dialog Base Package sets up a required set of base functionality for the media server ๐Ÿ’– It covers individual media primitives, like playing an announcement or collecting digits, plus composite operations like play and collect. When this package is used together with the MSML Dialog Group Package, the event-based mechanism is what controls the primitives. This package can also be combined with the MSML Speech Package to level up prompts with TTS and level up input collection with ASR ๐Ÿค–โœจ

In the sections that follow, the subsections of a primitive define child elements of that primitive. They aren't primitives themselves ๐Ÿงš They don't receive events or populate shadow variables, so don't go looking for them there ๐Ÿ™ˆ

9.7.1. <play> ๐ŸŽ€

okay so <play> is the element that makes the audio or video stream, bestie ๐ŸŽถ It MUST play in sequence the media made by its child elements <audio>, <video>, <media>, <tts>, and <var>. When it stops, either because a terminate event shows up or because all the media generation is done, the <playexit> element runs (if you've got one). At least one media generation element must be present ๐Ÿ’…

<play> has two states: generate and suspend. Media gets generated in generate and paused in suspend. Once it's in suspend, generation picks back up when the generate event arrives. The default starting state is generate โœจ

Audio MAY be generated in different languages by setting xml:lang on <play> and/or on its child elements. The children inherit the language, but each child MAY set its own. Except for physical audio clips, it's an error if a language is asked for and the media server can't render the audio in that language ๐Ÿ™ˆ

Attributes:

  • id: an optional identifier that can be referenced elsewhere for sending events to the play primitive ๐Ÿ†”
  • interval: the delay between stopping one iteration and starting the next. It does nothing unless iterate is also specified. Default is no interval.
  • iterate: how many times the media from the child media elements gets played. Each iteration is a full play of every child media element, in document order. Defaults to once '1'.
  • initial: the initial state for the play element. Default is "generate".
  • maxtime: the maximum allowed time for the <play> to complete โฐ
  • barge: whether audio announcements can be interrupted by DTMF detected during play-out. The DTMF digit that barges the announcement is stored in the digit buffer. Valid values are "true" or "false", and it's mandatory. When barge is applied to a conference target, DTMF digits detected from any conference participant MUST terminate the announcement ๐Ÿ“ž
  • cleardb: whether the digit buffer gets cleared before the announcement starts. Valid values are "true" or "false", and it's mandatory ๐Ÿงน
  • offset: an offset, measured in units of time, where the <play> starts generating media. Offset is only valid when all child media elements are <audio>.
  • skip: an amount of time used to skip through the media when "forward" and "backward" events arrive. Default is 3 s (three seconds) โฉ
  • xml:lang: the language to use for content that can be rendered in different languages ๐ŸŒ

Events:

The following describes input events to the media primitive object. The MSML Dialog Group Package allows an event exchange mechanism between primitives ๐Ÿซถ

  • pause: makes the play enter the suspend state โธ๏ธ
  • resume: makes the play enter the generate state โ–ถ๏ธ
  • forward: skips forward through the media. It only has an effect when all child media elements are <audio>.
  • backward: skips backward through the media. It only has an effect when all child media elements are <audio>.
  • restart: skips to the beginning of the media. It only has an effect when all child media elements are <audio>.
  • toggle-state: flips between the suspend and generate states ๐Ÿ”
  • terminate: ends the play and assigns values to the shadow variables ๐Ÿ›‘

Shadow Variables:

  • play.amt: the length of time the media was generated before the play was stopped. This doesn't include any time that passed while the play was in the suspend state.
  • play.end: the event that caused the play to stop. When the play stops because all media generation has completed, end gets assigned the value "play.complete" โœ…
Note: the barge and cleardb attributes are a simplified way to control play operations with implicit DTMF, no <group> or event exchange needed ๐Ÿงš When you use <play> inside the group framework and barge is specified, detecting a barge condition generates an implicit terminate event to the play primitive.

Here's what the child elements of <play> look like ๐Ÿ‘‘

9.7.1.1. <audio> ๐ŸŽง

The <audio> element identifies prerecorded audio to play. Local URI references may resolve to a single physical audio clip, a logical clip, or a provisioned sequence of clips (physical or logical). A logical clip is one that can be rendered differently based on the language attribute. Logical clips are provisioned for each of the languages a media server supports. Remote URI references get resolved according to the capabilities of the remote server ๐ŸŒ

Attributes:

  • uri: the location of the audio to be played. The file and http schemes are supported. Mandatory.
  • format: the encoding and file type of the audio resource. The format attribute is defined as a string of the form "audio/<filetype>;codecs=<codec>". The keyword 'audio' identifies audio content. The codecs field identifies the codec used to decode the audio file's content. If the format attribute isn't specified, the filetype MUST be determined from the URI, and the codec information MUST be determined from the media resource ๐Ÿ”
  • audiosamplerate: the audio sample rate in kHz. If it's not specified, the sample rate SHOULD be determined from the media resource.
  • audiosamplesize: the audio sample size in bits. If it's not specified, the sample size SHOULD be determined from the media resource.
  • iterate: how many times the audio is to be played. Defaults to once '1'.
  • xml:lang: the language to use when the URI identifies a logical clip, either directly or as part of a sequence ๐Ÿ—ฃ๏ธ

9.7.1.2. <video> ๐ŸŽฌ

The <video> element identifies prerecorded multimedia to play. Contents identified by the URI attribute may contain audio only, video only, or both audio and video. The media server SHOULD attempt to play both audio and video from the identified URI, if both are available in the content ๐Ÿฟ

Attributes:

  • uri: the location of the video or multimedia to be played. The file and http schemes are supported. Mandatory.
  • format: the encoding and file type of the video or multimedia resource. The format attribute is defined as a string of the form "video/<filetype>;codecs=<codecx>,<codecy>". The keyword 'video' identifies video-only media or media containing both audio and video. The codecs field identifies the audio and/or video codecs used to decode the file content, and the order of the codec values doesn't matter. When you've got audio and video content and use the 'video' keyword, the codecs=<codecx>,<codecy> field MAY be used to identify the audio codec and the video codec. If it's not specified, the codec information SHOULD be determined from the media file ๐ŸŽž๏ธ
  • audiosamplerate: the audio sample rate in kHz. If it's not specified, the sample rate SHOULD be determined from the media file.
  • audiosamplesize: the audio sample size in bits. If it's not specified, the sample size SHOULD be determined from the media file.
  • codecconfig: an optional special instruction string for codec configuration. The default is to send no special configuration string to the codec.
  • profile: a video profile name specific to the codec. If it's not specified, the default video profile of the codec SHOULD be selected.
  • level: a video profile level for the codec. The default is to send no profile information to the codec and let the codec pick an internal default ๐Ÿ“Š
  • imagewidth: the width of the video image in pixels. The default is to use the image width information from the media file.
  • imageheight: the height of the video image in pixels. The default is to use the image height information from the media file.
  • maxbitrate: the bitrate of the video signal in kbps. The default is to use the maximum bitrate information from the media file.
  • framerate: the video frame rate in frames per second. The default is to use the frame rate information from the media file.
  • iterate: how many times the media content is to be played. Defaults to once '1'.

9.7.1.3. <media> ๐ŸŽฅ

The <media> element identifies multimedia content for play. All content of the <media> element MUST start to play concurrently. This element may be used to generate a multimedia stream from two independent media resources, one identifying audio and the other identifying video ๐Ÿซง

The <media> element MUST contain at least one child element. The valid child elements of <media> are <audio> and <video>, as described earlier. The <media> element MUST contain at most one <audio> element or at most one <video> element ๐Ÿ™…โ€โ™€๏ธ

9.7.1.4. <var> ๐Ÿง 

The <var> element specifies the generation of audio from a variable, using prerecorded audio segments. A variable represents a semantic concept (like a date or a number) and dynamically produces the right speech for it ๐Ÿ—“๏ธ

Prerecorded audio lets an application vendor or service provider pick the exact voice for their audio, so they completely control the "sound and feel" of the service their end users get. It sounds super high quality and lets the variables blend seamlessly into the surrounding audio segments ๐Ÿ’–

Text to speech (TTS) using Speech Synthesis Markup Language (SSML) [n11] can also be used to render variables, but it may not sound as good, or give as complete control over the "sound and feel" or user experience. TTS is normally used for reading text like emails, and for very large vocabularies such as stock names. TTS makes a very clear difference between the variables and the surrounding audio segments. (See MSML Dialog Speech Package.) ๐Ÿค–

Attributes:

  • type: the type of variable. Mandatory. The variable type must be one of "date", "digits", "duration", "month", "money", "number", "silence", "time", or "weekday".
  • subtype: an optional clarification of the type. The specific values depend on the type ๐Ÿ”Ž
  • value: the text that should be rendered in a way that fits the type and subtype attributes. Mandatory.
  • xml:lang: the language to use when rendering the variable ๐ŸŒ

9.7.1.5. <playexit> ๐Ÿšช

The <playexit> element MUST be invoked when generation of all content of the <play> has come to completion. The contents of this element MAY be used to send events ๐Ÿ“จ

Attributes:

  • none ๐Ÿซฅ

9.7.2. <dtmfgen> ๐ŸŽ€

okay so the DTMF generator is the one that originates one or more DTMF digits in sequence ๐Ÿ“žโœจ it's giving phone keypad, bestie ๐Ÿซถ

Attributes:

  • id: an optional identifier that may be referenced elsewhere for sending events to the dtmfgen primitive ๐Ÿ’–
  • digits: a string of characters from the alphabet 0-9a-d#* that correspond to a sequence of DTMF tones. Mandatory. ๐Ÿ”ฅ
  • level: used to define the power level for which the tones will be generated. Expressed in dBm0 in a range of 0 to -96 dBm0. Larger negative values express lower power levels. Note that values lower than -55 dBm0 will be rejected by most receivers (TR-TSY-000181, ITU-T Q.24A). Default is -6 dBm0. ๐ŸŒธ
  • dur: the duration in milliseconds for which each tone should be generated. Implementations may round the value if they only support discrete durations. Default is 100 ms. โญ
  • interval: the duration in milliseconds of a silence interval following each generated tone. Implementations may round the value if they only support discrete durations. Default is 100 ms. ๐Ÿฆ‹

Events:

  • terminate: terminates DTMF generation and assigns values to the shadow variables. ๐Ÿ’…

Shadow Variables:

  • dtmfgen.end: contains the event that caused DTMF generation to stop. ๐Ÿ‘‘

The following sections describe the child elements of <dtmfgen>. ๐Ÿงš

9.7.2.1. <dtmfgenexit> ๐ŸŒˆ

ngl this one is so important ๐Ÿ˜ญ the <dtmfgenexit> element MUST be invoked when the DTMF generation operation completes or is terminated as a result of receiving the terminate event. it MAY be used to send events when the DTMF generation has completed. no cap, that's the whole vibe ๐Ÿ’œ

Attributes:

  • none

9.7.3. <tonegen> ๐Ÿ“

the tone generator is where it gets customized, periodt โœจ you can compose a sequence of varying tones with optional silence intervals using the <tonegen> element. its child elements, namely <tone> and <silence>, specify a single tone or a sequence of tones ๐ŸŽถ

Attributes:

  • id: an optional identifier that may be referenced elsewhere for sending events to the tonegen primitive ๐Ÿฆ‹
  • iterate: a numeric value specifying the total number of iterations. A value of 'forever' represents infinite repetitions. Optional. Default is 1. ๐Ÿ’–

Events:

  • terminate: terminates tone generation and assigns values to the shadow variables. ๐Ÿ”ฅ

Shadow Variables:

  • tonegen.end: contains the event that caused tone generation to stop. ๐ŸŒธ

The following sections describe the child elements of <tonegen>. ๐Ÿซถ

9.7.3.1. <tone> ๐Ÿ’…

the <tone> element specifies a single tone with an optional silence interval, and honestly the main character energy is real ๐Ÿ‘‘ the tone specification consists of two tone frequencies, their attenuation values, a duration of the tone, and the number of times to repeat the tone.

Attributes:

  • duration: time duration or length of the individual tone, specified in "ms" or "s" in increments of 10 ms. A value of 0 represents an infinite duration. Mandatory. โญ
  • iterate: specifies the number of times to execute the contents of <tone> element. A value of 'forever' represents infinite repetitions. Optional. Default is 1. ๐ŸŒˆ

Events:

  • none

Child Elements:

The child elements of <tone> element specify a single tone and an optional silence interval to be inserted at the end of tone generation. A tone is defined by <tone1> and <tone2> elements. Each <tone> element MUST contain at least one of <tone1> or <tone2>, or MAY contain <tone1> and <tone2> exactly once. ๐Ÿงš

  • <tone1>

Attributes:

  • freq: specifies the frequency of the first tone in "Hz", ranging from 0 to 3999 Hz. Mandatory. ๐ŸŽ€
  • atten: specifies the attenuation level expressed in dBm0, ranging from 0 to -96 dBm0. Mandatory. ๐Ÿ’œ
  • <tone2>

Attributes:

  • freq: specifies the frequency of the second tone in "Hz", ranging from 0 to 3999 Hz. Mandatory. ๐Ÿ“
  • atten: specifies the attenuation level expressed in dBm0, ranging from 0 to -96 dBm0. Mandatory. โœจ
  • <silence> - Refer to the silence element definition below. ๐Ÿฆ‹

9.7.3.2. <silence> ๐Ÿ™ˆ

the <silence> element inserts a silence interval as optional content of <tonegen> or <tone> elements. it's the pause that makes the whole thing slay ๐Ÿคซ

Attributes:

  • duration: specifies the amount of silence interval in "ms" or "s", in increments of 10ms. Mandatory. ๐ŸŒธ

Events:

  • none

9.7.3.3. <tonegenexit> ๐ŸŒˆ

same energy as the dtmfgen exit, bestie ๐Ÿ’– the <tonegenexit> element MUST be invoked when the tone generation operation completes or is terminated as a result of receiving the terminate event. the <tonegenexit> element MAY be used to send events when the tone generation has completed. iykyk ๐Ÿซถ

Attributes:

  • none

9.7.4. <record> ๐ŸŽ€

okay bestie, <record> is the element that literally makes recordings ๐ŸŽ™๏ธ ๐Ÿ’– Like <play>, it has two states, create and suspend โœจ In create, received media becomes part of the recording. In suspend, that media gets discarded ๐Ÿซถ

Recording MUST be terminated when a terminate event is received, or when a nospeech event is received and no audio has been recorded yet ๐Ÿ’€ <record> also tells the different terminate events apart ๐Ÿ‘‘

An optional <play> element MAY be specified as a child element of <record> ๐Ÿงš This makes a full play-record combo, where the prompts inside <play> get played before the recording starts ๐ŸŽ€

Note: prespeech, postspeech, and termkey give you a simpler way to control record operations using implicit DTMF and VAD, no <group> or event exchange mechanism needed ๐Ÿ™ˆ

Attributes:

  • id: an optional identifier that can be referenced elsewhere for sending events to the record primitive ๐Ÿฆ‹
  • append: a boolean that decides whether the recording is allowed to be appended to an existing file if dest already exists. Default is "false". This attribute is ignored if the scheme is http ๐ŸŒธ
  • dest: the destination for the recording. It will contain audio only, video only, or both audio and video, depending on the stream(s) being recorded. Recording MAY be either local or external based on the attribute value. File and http schemes are supported ๐Ÿ“
  • audiodest: the destination for the audio-only recording. Recording MAY be either local or external based on the attribute value. All combinations of dest, audiodest, and videodest are valid. File and http schemes are supported ๐ŸŽง
  • videodest: the destination for the video-only recording. Recording MAY be either local or external based on the attribute value. All combinations of dest, audiodest, and videodest are valid. File and http schemes are supported ๐Ÿ“น
  • format: defines the encoding and file type of the recording. It's a string shaped like "audio|video/filetype;codecs=x,y". The keyword audio means an audio-only recording, while video means a video-only recording or an audio plus video recording. The codecs field names the audio and/or video codecs to use, and the order of the codec values doesn't matter. When you record audio and video using the video keyword, the codecs=x,y field MAY be used to identify the audio codec and the video codec. Mandatory ๐Ÿ’…
  • codecconfig: an optional special instruction string for codec configuration. Default is to send no special configuration string to the codec ๐Ÿงฉ
  • audiosamplerate: the audio sample rate in kHz. If it's not specified, the sample rate SHOULD be determined from the media source ๐Ÿ”Š
  • audiosamplesize: the audio sample size in bits. If it's not specified, the sample size SHOULD be determined from the media source ๐ŸŽš๏ธ
  • profile: a video profile name specific to the codec. If it's not specified, the default video profile of the codec SHOULD be selected for the recording ๐ŸŽฌ
  • level: a video profile level passed to the codec. Default is to send no profile information to the codec and let the codec pick an internal default ๐ŸŒˆ
  • imagewidth: the width of the video image in pixels. Default is to use the image width information from the media source ๐Ÿ“
  • imageheight: the height of the video image in pixels. Default is to use the image height information from the media source ๐Ÿ“
  • maxbitrate: the bitrate of the video signal in kbps. Default is to use the maximum bitrate information from the media source โญ
  • framerate: the video frame rate in frames per second. Default is to use the frame rate information from the media source ๐ŸŽž๏ธ
  • initial: defines the initial state for the record element. Default is "create", which starts the recording as soon as the <record> element is executed. The initial attribute only applies when <record> is used within the <group> structure ๐Ÿš€
  • maxtime: defines the maximum length of the recording in units of time. Mandatory โณ
  • prespeech: a timer value, in seconds, for detecting absence of audio energy at the start of the record operation. If no audio energy is detected for the time set by prespeech, the recording gets terminated. Default is 0 s, which doesn't activate the prespeech timer ๐Ÿคซ
  • postspeech: a timer value, in seconds, for detecting absence of audio energy while the recording is in progress. If absence of audio energy is detected for the amount set by the postspeech timer, the recording gets terminated. Default is 0 s, which disables terminating a recording due to postspeech silence ๐Ÿ˜ถ
  • termkey: a single DTMF key that, when detected, terminates the recording. Without this attribute, the recording can't be terminated by DTMF digits. When termkey is specified, the detected DTMF digit terminates the recording and is not entered in the digit buffer ๐Ÿ”‘

Events:

The following describes input events to the media primitive object. The MSML Dialog Group Package allows an event exchange mechanism between primitives ๐Ÿ’Œ

  • pause: makes the record enter the suspend state. Received media is discarded โธ๏ธ
  • resume: makes the record resume if it was suspended. Otherwise it does nothing โ–ถ๏ธ
  • toggle-state: toggles the suspend / create state ๐Ÿ”
  • terminate: terminates the recording and assigns values to the shadow variables ๐Ÿ›‘
  • terminate.cancelled: terminates the recording and assigns values to the shadow variables. If the dest attribute used the file scheme, the local recording is deleted. Applications are responsible for removing external files created using the http scheme ๐Ÿ—‘๏ธ
  • terminate.finalsilence: terminates the recording and assigns values to the shadow variables. If the dest attribute used the file scheme, the final silence is removed from the recording โœ‚๏ธ
  • nospeech: terminates the recording and assigns values to the shadow variables if it's received and no recording has been created yet. The nospeech event is ignored if audio has already been recorded ๐Ÿ™‰

Shadow Variables:

  • record.len: the actual length of the recording, measured in units of time. This doesn't include time that may have passed while the record was in the suspend state โŒ›
  • record.end: contains the event that caused the record to terminate. When the record terminates because maxtime is exceeded, end is assigned the value "record.complete.maxlength" ๐Ÿ
  • record.recordid: contains the value of the dest attribute, if supplied. Otherwise it contains a media server assigned record identifier ๐Ÿชช

Record termination due to prespeech silence gets the value "record.failed.prespeech". Record termination due to postspeech silence gets the value "record.complete.postspeech". Record termination due to DTMF detection gets the value "record.complete.termkey" ๐Ÿ’…

The following sections describe the child elements of <record> ๐Ÿงš

9.7.4.1. <play>

The optional <play> element, as a child element of <record>, lets a prompt play before recording starts. The record operation starts at the end of the play sequence, or if the play is barged by DTMF, assuming barge=true is specified for <play> ๐ŸŽต For the full scoop, check out the <play> element ๐Ÿ’–

9.7.4.2. <tonegen>

The optional <tonegen> element, as a child element of <record>, lets a tone or sequence of tones play before recording starts. The record operation starts at the end of the tone generation ๐Ÿ”” For the complete description, refer to the <tonegen> element โœจ

9.7.4.3. <recordexit>

The <recordexit> element MUST be invoked when the record operation completes, or when the recording is terminated because it received the terminate event ๐Ÿฆ‹ The <recordexit> element MAY be used to send events when the recording has completed ๐Ÿ“จ

Attributes:

  • none ๐Ÿซถ

9.7.5. <dtmf> or <collect> โœจ

Okay bestie, DTMF input has a few jobs in MSML dialogs ๐ŸŽ€ First, it can trigger events that change how other primitives process media ๐Ÿฆ‹ Second, it collects DTMF digits from a media stream and reports them back to the user of the MSML dialog ๐Ÿ“ฒ And ngl, a lot of the time DTMF detection does both at once ๐Ÿ’… Barge is the classic example: a prompt gets stopped because of DTMF input, but there might still be more digits to collect ๐Ÿ™ˆ

DTMF detection can handle multiple recognition patterns at the same time ๐ŸŒˆ Each pattern can send a different event, which is how you build DTMF controls ๐ŸŽฎ Or, one pattern can represent a whole collection while another pattern, a substring of the first, acts as the barge indication ๐Ÿ’œ

An optional <play> element MAY be specified as a child element of <dtmf> or <collect> ๐ŸŽถ That gives you a complete play-collect operation, where the prompts inside <play> get played before DTMF digit collection ๐Ÿงš

Heads up ๐Ÿšจ: all patterns share the same digit collection buffer, inter-digit timing, a single <nomatch> element, and a single <noinput> element. So multiple patterns might not be the move for simultaneous collections that serve different purposes ๐Ÿ™… When that's what you need, separate <dtmf> elements should be used instead ๐Ÿซถ

<dtmf> terminates if any of the <pattern>, <noinput>, or <nomatch> elements are matched the maximum number of times they're allowed ๐Ÿ’€ The number of times they may match can be set as an attribute of <dtmf> or of the individual child elements ๐Ÿ”ฅ

Element identifier <dtmf> is equivalent to <collect> โœจ However, <collect> is the preferred name ๐Ÿ’… MSML clients SHOULD use <collect>, while MSML servers SHOULD support both ๐Ÿซถ

Attributes:

  • id: an optional identifier that may be referenced elsewhere for sending events to this primitive ๐ŸŽ€
  • cleardb: a boolean that says whether the buffer for digit collection gets cleared of any collected digits when the element is instantiated. If it's set to false, any digits currently in the buffer MUST be immediately compared against the pattern elements ๐Ÿงน
  • fdt: defines the first-digit timer value. The first-digit timer starts when DTMF detection is first invoked. If no DTMF digits are detected during this initial interval, the <noinput> element MUST be invoked. Optional, default is 0 s (wait forever for the first digit) โณ
  • idt: defines the inter-digit timer used when digits are being collected. When specified, the timer starts when the first digit is detected and restarts on each subsequent digit. Timer expiration applies to all patterns. After that, if any patterns remain active and a nomatch element is specified, the nomatch is executed and DTMF input MUST terminate. The idt attribute should only be used when digit collection is being performed. Optional, default is 4 s ๐Ÿ•ฐ๏ธ
  • edt: defines the extra-digit timer value. It specifies how long the media server MUST wait after a match to detect a termination key, if one is specified by the <pattern> element. Optional, default is 4 s ๐Ÿ”‘
  • starttimer: a boolean that defines whether the first digit timer (fdt) starts initially. When set to false, the starttimer event must be received for it to start. Default is "false" ๐Ÿšฆ
  • iterate: specifies the number of times the <pattern>, <noinput>, and <nomatch> elements may be executed, unless those elements specify differently. The value "forever" MAY be used to indicate that these may be executed any number of times. Default is once 1 ๐Ÿ”
  • ldd: defines the minimum duration a digit must be held for it to be detected as a long DTMF digit. A long DTMF digit event MUST be treated as a single DTMF event, and MUST contain an extra character L at the end to be told apart from the other regular digit events. For example, #L and # are different DTMF events ๐Ÿง Optional, default of 0 s. A value of 0 s disables long DTMF digit detection and reporting. The attribute value is an integer with a valid range from 100 ms to 100 s (units MUST be supplied) ๐Ÿ“

Events:

The following describes input events to the media primitive object. The MSML Dialog Group Package allows an event exchange mechanism between primitives ๐Ÿค

  • starttimer: starts the first digit timer (fdt) if it hasn't already been started. Has no effect otherwise ๐Ÿ
  • terminate: terminates the DTMF input and assigns values to the shadow variables ๐Ÿ›‘

Shadow Variables:

  • dtmf.digits: the string of DTMF digits that have been received (the contents of the digit buffer) ๐Ÿ“
  • dtmf.len: the number of digits in the digit buffer ๐Ÿ”ข
  • dtmf.last: the last digit in the digit buffer โ˜๏ธ
  • dtmf.end: contains the event that caused the <dtmf> to terminate, or is assigned one of "dtmf.match", "dtmf.noinput", or "dtmf.nomatch", depending on which of the corresponding elements reached its maximum ๐Ÿ†

The following sections describe the child elements of <dtmf> or <collect> ๐Ÿงธ

9.7.5.1. <play>

The optional <play> element, as a child element of <dtmf> or <collect>, lets a prompt play before DTMF digit collection ๐ŸŽต DTMF digit collection starts at the end of the play sequence, or if the play gets barged by DTMF, assuming barge=true is specified for <play>. For the full scoop, check out the <play> element ๐Ÿ“–

9.7.5.2. <pattern>

The <pattern> element describes one or more DTMF digits that are to be recognized ๐ŸŽฏ When the pattern is matched, the child elements MUST be executed ๐Ÿ™Œ

Attributes:

  • digits: the digit pattern that should be matched. Mandatory ๐Ÿ”ข
  • format: an enumerated value that defines the format used to express the digit pattern. The format may be "mgcp" or "megaco" for patterns expressed as a digit map from those specifications, or as one of the simple built-in formats defined within this specification. Currently, a single built-in format, "moml+digits", is defined. It allows a match based on either one or more specific digits, or on a specific length specification with an optional return key. "moml+digits" is the default ๐Ÿงฉ
  • iterate: specifies the number of times the <pattern> may be matched. The value "forever" may be used to indicate that <pattern> may be matched any number of times. This value overrides any specified in <dtmf>. Default is once 1 ๐Ÿ”

9.7.5.3. <detect>

The contents of the <detect> element MUST be executed whenever any DTMF is first detected ๐Ÿ‘€ It MUST be matched at most once ๐ŸŽˆ

Attributes:

  • none ๐Ÿซง

9.7.5.4. <noinput>

The <noinput> element is used when DTMF is being collected ๐ŸŽค Children of the <noinput> element MUST be executed when DTMF has not been detected and the first digit timeout occurs โฐ

Attributes:

  • iterate: specifies the number of times the <noinput> may be triggered. The value "forever" may be used to indicate that <noinput> may be triggered any number of times. This value overrides any specified in <dtmf>. Default is once 1 ๐Ÿ”

9.7.5.5. <nomatch>

The <nomatch> element is used when DTMF is being collected ๐ŸŽค Children of the <nomatch> element MUST be executed when it is determined that none of the individual patterns can be matched ๐Ÿšซ

Attributes:

  • iterate: specifies the number of times the <nomatch> may be triggered. The value "forever" may be used to indicate that <nomatch> may be triggered any number of times. This value overrides any specified in <dtmf>. Default is once 1 ๐Ÿ”

9.7.5.6. <dtmfexit>

The <dtmfexit> element MUST be invoked when the dtmf input completes because one of <pattern>, <noinput>, or <nomatch> has occurred its maximum number of times ๐Ÿšช

Attributes:

  • None ๐Ÿซง

9.7.6. <moml>

The root element <moml> MUST be used when the document is a stand-alone MSML dialog, where the invoking application media type indicates 'application/moml+xml' ๐Ÿ“„ Additionally, for backwards compatibility, the <moml> element MUST be used within <dialogstart>, which contains an inline embedded MSML dialog ๐Ÿง

Valid contents of <moml> are all elements described within this MSML Dialog Base Package ๐Ÿงบ

Attributes:

  • version: "1.0" Mandatory ๐Ÿท๏ธ
  • id: an identifier unique to this object. Events returned from the MSML dialog (the "target" attribute of a <send> is equal to "source") will be correlated with this identifier. Mandatory ๐Ÿชช

Events:

  • terminate: terminates the MOML context. A terminate event gets sent to the currently executing <group> or primitive ๐Ÿ’ฅ

9.8. MSML Dialog Group Package โœจ

okay so the group package is the thing that lets you run a bunch of primitives at the same time ๐ŸŽ€ You wrap them in a <group> element and suddenly they're all doing their thing concurrently. Groups define how media flows between those primitives, and each group has one or more inputs and one or more outputs. A <group> is basically a declaration of a fancy media processing operation ๐Ÿ’… The event interaction between primitives (see the following subsection) lives inside one or more groups. BUT groups don't scope events. They just say "these are running at the same time," and a primitive has to be executing in order to receive an event ๐Ÿฆ‹

Using groups is totally optional. It's just what you reach for when you want complex services built out of events flowing between primitives. For simpler stuff like play/collect or play/record, you don't need the group mechanism at all ๐ŸŒธ The MSML Dialog Group Package depends on the MSML Dialog Base Package, so that's a must-have bestie ๐Ÿ’œ

Groups can also describe media objects that transform a stream while letting the application or the user control the transformation. Like, a gain control that reacts to user speech or DTMF input? Iconic ๐Ÿ‘‘ In that case, a recognition primitive sends events to a gain control primitive.

Groups have one attribute that defines the media flow inside them. They also have a dimension, which is how many media inputs and outputs they have. Right now, dimensions of 1 and 2 are supported based on the group topology. Dimension 1 is a group with one input and one output, and dimension 2 is a group with two inputs and two outputs ๐Ÿ“

Media flow to and from the primitives in a group is based on the topology attribute of the <group> element. That attribute names a topology schema, and the schema implies the group's dimension โœจ

There are a few common ways primitives get wired together, and a schema is basically a convenient template you can slap onto multiple primitives without spelling out every single media relationship yourself ๐Ÿงš These two schemas are initially defined for one-dimensional groups:

  • parallel: media sent to the group goes to every primitive that has an input. The group bridges the output from every primitive that has an output into a single common group output.
  • serial: the first primitive listed in the group receives the media sent to the group. Its output gets connected to the input of the next primitive defined within the group, and so on, until the last primitive in the group becomes the group output.

Here are the two topologies in diagrams. The one on the left is parallel and the one on the right is serial ๐ŸŒˆ

           /-> P1 --\
          /          \
   G(in) +---> P2 ----> G(out)     G(in) --> P1 --> P2 --> P3 --> G(out)
          \          /
           \-> P3 --/

More complex media flows MAY be created by nesting serial and parallel groups inside each other. For example, the diagram below shows a serial group nested inside a star topology. Bestie, this is where it gets spicy ๐Ÿ”ฅ

               /-----> P1 ------------------------\
              /                                    \
      Gs(in) +-> Gp(in) --> P2 --> P3 --> Gp(out) -+> Gs(out)

Why would you do this? Picture a record operation where DTMF gets clamped out of the recording itself, but a DTMF key press still stops the recording. In that setup, P1 is a DTMF recognizer, P2 is a clamp primitive, and P3 is a recorder. The example below shows it. It leaves out child elements and attributes that aren't related to the core concept. The next section covers sending events, and the details of each primitive are in section 4 ๐Ÿ“ผ

   <group topology="parallel">
      <dtmf/>
      <group topology="serial">
         <clamp/>
         <record/>
      </group>
   </group>

There's also one schema, "fullduplex", for a two-dimensional group. A full-duplex two-dimensional group has exactly two immediate children. Those children can be primitives or other one-dimensional groups. A "fullduplex" group must only be used as the top-most group and must not be nested. Each primitive (P1) and group (G2) becomes one half of the full-duplex group, as shown in the diagram below ๐Ÿ’–

      G-A(in1)  +-> G2 --> G-B(out1)

      G-A(out2) <-- P1 <-+ G-B(in2)

Full-duplex groups are symmetrical when both halves are the same, and asymmetrical when they differ. Asymmetric groups need a name for each side. The left side is the input of the first child of the full-duplex group combined with the output of the second child. The right side is the reverse. In the diagram above, these sides are labeled A and B respectively ๐Ÿฆ‹

The user-operated gain control from earlier in this subsection is a perfect full-duplex example. The gain should operate on the audio the user hears, but the gain is controlled by recognizing things like DTMF or spoken commands in the media the user originates. The XML below does exactly that and matches the media flow in the diagram above. If the user's audio isn't needed for anything except controlling the gain, then the <relay> isn't required and the internal group could be left out. A complete XML description is in the examples section ๐ŸŽ€

   <group topology="fullduplex">
      <group topology="parallel">
         <dtmf/>
         <relay/>
      </group>
      <gain/>
   </group>

Primitives within a group MUST begin concurrently but MAY finish asynchronously, based on the events they receive or when their task completes ๐Ÿ’… A group MUST terminate when all of the primitives within it have completed. If the group contains a <groupexit> element, then the contents of that element MUST be executed as part of group termination ๐Ÿซถ

A group itself MAY receive a terminate event requesting termination. A terminate event sent to the group causes a terminate event to be sent to each of its currently active primitives. The <groupexit> element is NOT executed until every primitive has processed its terminate event ๐Ÿ˜ญ

9.8.1. <group>

The <group> element lets the contained primitives execute concurrently ๐ŸŒธ

Attributes:

  • topology: specifies a schema that defines the flow of media within the group. Three schemas are initially defined. "fullduplex" is for use with two-dimensional groups. "parallel" and "serial" are for use with one-dimensional groups. The definitions of these topologies are in section 9.8. Mandatory.
  • id: identifies the name of the group. Mandatory when groups are nested.

Events:

  • terminate: causes a terminate event to be sent to each element contained within the group.

9.8.2. <groupexit>

The <groupexit> element allows events to be sent when group processing completes. Group processing completes when all contained primitives terminate ๐Ÿงš

Attributes:

  • none

Events:

  • none

9.9. MSML Dialog Transform Package ๐Ÿฆ‹

The MSML Dialog Transform Package gathers together the simple primitives that work as filters on half-duplex media streams ๐Ÿ’œ

9.9.1. <vad>

Voice activity detection (VAD) is used to detect voice and silence when speech recognition isn't required. Like speech and DTMF, a VAD has different media conditions it can match. Those conditions can be qualified by a minimum length of time they must last before they count as recognized โœจ

Attributes:

  • id: an optional identifier that may be referenced elsewhere for sending events to the vad primitive.
  • starttimer: a boolean value that defines whether the timer is started to allow recognition of the initial condition (voice, silence). When set to false, the starttimer event must be received in order for the initial condition to be recognized. The timer does not affect recognition of the transition conditions. Default is "false".

Events:

  • starttimer: starts the timer to allow recognition of the initial condition if it has not already been started. Has no effect otherwise.
  • terminate: terminates voice activity detection.

Shadow Variables:

  • none

The following sections describe the child elements of <vad> ๐ŸŒˆ

9.9.1.1. <voice>, <silence>, <tvoice>, <tsilence>

Each child element corresponds to a condition that a VAD can detect. The first two detect when voice or silence has been initially present for a minimum length of time since the VAD was started. The last two require that a transition to the voice or silence condition occurs first ๐Ÿ“

Attributes:

  • len: the length of time the condition must persist in order to be recognized. Mandatory. For <tvoice> and <tsilence>, the length of time applies only to the final recognized condition.
  • sen: the maximum length of time the condition not being detected may occur without causing the detector to begin measuring that condition.

9.9.2. <gain>

Gain MAY be used to adjust the gain of a media stream by a specific amount ๐Ÿ”ฅ Applying <gain> removes any previous connection AGC setting used by the <agc> element.

Attributes:

  • id: an optional identifier that may be referenced elsewhere for sending events to the gain primitive.
  • incr: an increment, expressed in dB, used to adjust the gain when "louder" and "softer" events are received. Default is 3 dB.
  • amt: a specific gain to apply, specified in dB. Mandatory.

Events:

  • mute: self-explanatory ๐Ÿ™ˆ
  • unmute: self-explanatory ๐Ÿ™ˆ
  • reset: sets the gain to zero dB.
  • louder: makes the audio on a stream louder.
  • softer: makes the audio on a stream quieter.
  • amt: sets the gain to the specified value between -96 dB and 96 dB.

9.9.3. <agc>

Automatic gain control MAY be used to have a media server automatically adjust the gain of a media stream ๐Ÿค– Applying <agc> removes any previous connection gain setting used by the <gain> element.

Attributes:

  • id: an optional identifier that may be referenced elsewhere for sending events to the gain primitive.
  • tgtlvl: the desired target level for AGC, specified in dBm0 with a valid range of -40 to 0. Mandatory.
  • maxgain: an optional attribute used to specify the maximum gain that AGC will apply, specified in dBm0 with a valid range of 0 to 40, with a default of 10.

Events:

  • mute: self-explanatory ๐Ÿ™ˆ
  • unmute: self-explanatory ๐Ÿ™ˆ

9.9.4. <gate>

The <gate> element is a simple filter that passes or halts media, regardless of the media stream's format, based on the events it receives. <gate> shares the same mute and unmute events as the gain primitives <gain> and <agc>, for compatibility ๐Ÿ’…

Attributes:

  • id: an optional identifier that may be referenced elsewhere for sending events to the gate primitive.
  • initial: the values "pass" and "halt" define whether media is initially allowed to pass. Default is to pass.

Events:

  • mute: halts media flow through the primitive.
  • unmute: allows media to pass through the primitive.

9.9.5. <clamp> ๐Ÿซง

okay so this one is giving DTMF filter energy ๐ŸŽ€. This element MAY be used to filter DTMF tones out of a media stream. Anything that isn't a DTMF tone just passes straight through unchanged โœจ.

  • id: an optional identifier that can be referenced elsewhere for sending events to the clamp primitive.

Events: none.

9.9.6. <relay> ๐Ÿฆ‹

this one is so simple it's iconic ๐Ÿ’…. The <relay> is a basic primitive that copies whatever comes in to the output. no drama, no notes ๐Ÿซถ.

  • id: an optional identifier that can be referenced elsewhere for sending events to the relay primitive.

Events: none.

9.10. MSML Dialog Speech Package ๐ŸŽ™๏ธ

the MSML speech package is where the voice stuff lives ๐Ÿ—ฃ๏ธโœจ. It defines functionality that MAY be used for automatic speech recognition, <speech>, and it extends the <play> primitive from the MSML Dialog Base Package so it can do speech synthesis too ๐ŸŒˆ. Because of that, this package depends on the MSML Dialog Base Package, so bestie you need that one first ๐Ÿ’œ.

9.10.1. <speech> ๐Ÿ‘‚

the <speech> element switches on grammars or user input rules tied to speech recognition ๐Ÿ”ฅ. If you specify more than one grammar, they all get switched on. All the active grammars share the same timers, recognition attributes, and <noinput> and <nomatch> elements, which is so iconic and efficient ๐Ÿ™Œ. Each grammar can have its own <match> element too.

<speech> ends if any of the <grammar>, <noinput>, or <nomatch> elements hit the max number of matches they're allowed. The number of allowed matches can be set as an attribute on <speech> itself or on the individual child elements ๐ŸŽ€.

Attributes:

  • id: an optional identifier that can be referenced elsewhere for sending events to the speech primitive.
  • noint: sets a time window in which speech input has to start. If it doesn't, the associated <noinput> element gets invoked ๐Ÿ˜ญ.
  • norect: sets a maximum time window in which speech has to begin to be matched. If that doesn't happen, the associated <nomatch> element gets invoked ๐Ÿ’€.
  • spcmplt: sets how much silence is needed after speech before a result gets finalized, in the case where there's a complete match of an active grammar ๐Ÿค. After that silence, the right <match> element gets triggered if the result is above the confidence level. If not, a <nomatch> element gets triggered.
  • spincmplt: sets how much silence is needed after speech before a result gets finalized, in the case where there's an incomplete match of all the active grammars ๐Ÿฅฒ. After that silence, the <nomatch> element gets triggered.
  • confidence: the minimum confidence level the recognizer has to have before it counts a recognition result as matching a grammar. It's an integer from 1-100 ๐Ÿ’ฏ.
  • sens: sets how sensitive the recognizer is when it's deciding whether speech is present ๐Ÿ‘€. Lower sensitivity may be needed so the recognizer still works well with lots of background noise or line echo ๐Ÿ”Š.
  • starttimer: a boolean that decides whether the no input (noint) and no recognition (norect) timers start right away. When it's set to false, the starttimer event has to be received before they start. The default is "false" ๐Ÿ•ฐ๏ธ.
  • iterate: sets how many times the <grammar>, <noinput>, and <nomatch> elements can run, unless those elements say something different. The value "forever" can be used to mean they can run any number of times โ™พ๏ธ. The default is once '1' ๐Ÿงš.

Events:

  • sens: sets the sensitivity of the recognizer as described above ๐ŸŽš๏ธ.
  • starttimer: starts the no input (noint) and no recognition (norect) timers if they haven't been started already. It does nothing otherwise ๐Ÿ™ƒ.
  • terminate: ends the speech input and assigns values to the shadow variables ๐Ÿ›‘.

Shadow Variables:

  • speech.end: holds the event that caused the <speech> to end, or it gets set to one of "speech.match", "speech.noinput", or "speech.nomatch", depending on which of the matching elements hit its max ๐Ÿ.
  • speech.results: holds the results of a matched grammar. The results are formatted with the Natural Language Semantics Markup Language (NLSML) [n4] ๐Ÿงพ. When this variable gets referenced to return results, the results come back as a separate MIME entity ๐Ÿ“ฆ.

The following sections describe the child elements of <speech> ๐Ÿ‘‡.

9.10.1.1. <grammar> ๐Ÿ“–

the <grammar> element specifies and activates a speech grammar using Speech Recognition Grammar Specification (SRGS) [n3] XML notation ๐Ÿง . Grammars can be referenced by a URI or defined inline. Child elements of <match> MUST be executed when the specified speech grammar is matched ๐Ÿ™Œ.

Attributes:

  • uri: specifies where the SRGS grammar lives when it isn't defined inline ๐Ÿ“.
  • iterate: specifies how many times the <grammar> can be matched. The value "forever" MAY be used to mean <grammar> can be matched any number of times โ™พ๏ธ. This value overrides any value set in <speech>. The default is once '1' โœจ.

9.10.1.2. <match> ๐ŸŽฏ

<match> is a child of <grammar>, and it specifies the actions to take when the matching grammar gets matched ๐Ÿ’….

9.10.1.3. <noinput> ๐Ÿคซ

the <noinput> element gets used when speech is being recognized ๐ŸŽ™๏ธ. Children of the <noinput> element MUST be executed when speech hasn't been detected and the no input timeout (noint) happens ๐Ÿ˜ฌ.

Attributes:

  • iterate: specifies how many times the <noinput> can be triggered. The value "forever" may be used to mean <noinput> can be triggered any number of times โ™พ๏ธ. This value overrides any value set in <speech>. The default is once '1' ๐Ÿงš.

9.10.1.4. <nomatch> ๐Ÿ™…โ€โ™€๏ธ

the <nomatch> element also gets used when speech is being recognized ๐ŸŽง. Children of the <nomatch> element MUST be executed when it's determined that none of the active grammars will match ๐Ÿšซ.

Attributes:

  • iterate: specifies the maximum number of times the <nomatch> can be triggered. The value "forever" MAY be used to mean <nomatch> can be triggered any number of times โ™พ๏ธ. This value overrides any value set in <speech>. The default is once '1' โœจ.

9.10.1.5. <speechexit> ๐Ÿšช

the <speechexit> element MUST be invoked when the speech input completes because one of <grammar>, <noinput>, or <nomatch> has happened its maximum number of times ๐Ÿƒโ€โ™€๏ธ๐Ÿ’จ.

Attributes: none

9.10.2. <play> ๐Ÿ”Š

the <play> element, as defined in the MSML Dialog Base Package, gets a new child element that synthesizes speech ๐Ÿค–๐ŸŽถ. From an XML perspective, <tts> is a member of a media substitution group ๐Ÿงฉ. See the schema at the end of this document for details ๐Ÿ“„.

The following sections describe the child elements of <play> ๐Ÿ‘‡.

9.10.2.1. <tts> ๐Ÿ—ฃ๏ธ

contents of the <tts> element get rendered with text-to-speech services, and they must be compliant with the SSML specification [n11] ๐Ÿ’–. Element content MAY be plain text, contain the SSML <speak> element, or the uri attribute should identify where the text to be rendered lives ๐Ÿ“.

Attributes:

  • uri: identifies the location of the text to be rendered. The file and http schemes are supported ๐ŸŒธ.
  • iterate: specifies how many times the text-to-speech block gets rendered. It defaults to once '1' ๐Ÿงš.
  • xml:lang: specifies the language to use when it isn't explicitly set as an attribute on <speak> ๐ŸŒ.

9.11. MSML Dialog Fax Detection Package ๐Ÿ“ 

the Fax Detection Package defines primitives that let a media server provide facsimile detection services ๐Ÿฆ–โœจ.

9.11.1. <faxdetect> ๐Ÿ”

fax tone detection is used to spot the T.30 Calling Tone (CNG) or the Called Station Identification (CED) tone in a media stream ๐Ÿ‘‚๐Ÿ’œ. Child elements of <faxdetectexit> MUST be executed when a CNG tone is detected ๐Ÿ™Œ.

  • id: an optional identifier that can be referenced elsewhere for sending events to the faxdetect primitive.

Events:

  • terminate: ends fax tone detection and assigns values to the associated shadow variables ๐Ÿ›‘.

Shadow Variables:

  • faxdetect.tone: a string that specifies the fax tone type the media server detected. Values supported SHOULD include "CED", "CNG", or an empty string ๐ŸŽ€. The empty string MUST be used if fax tone detection ended before a fax tone was detected, which results in the <faxdetectexit> element getting executed ๐Ÿซ .
  • faxdetect.end: a string value that specifies why <faxdetect> ended ๐Ÿ. Values supported SHOULD include "faxdetect.complete" (because a CED or CNG tone was detected), "faxdetect.failed.noresource" (failed because the media server ran out of resources), "faxdetect.failed" (failed for any other reason), "faxdetect.terminated" (terminated by <dialogend>), or undefined ๐ŸŒˆ.

9.11.2. <faxdetectexit> ๐Ÿšช

the <faxdetectexit> element MUST be invoked when fax detection, which was started via <faxdetect>, ends ๐Ÿƒโ€โ™€๏ธ. Its child elements, <send> and <exit>, let the media server report events ๐Ÿ“ฃ.

Attributes: none

9.12. MSML Dialog Fax Send/Receive Package ๐Ÿ“จ

9.12.1. <faxsend> ๐Ÿ“ 

okay so <faxsend> is the calling fax terminal energy ๐Ÿ’… it's the one that sends a set of pages, main character behavior fr. It can also ask the called terminal to send pages back instead of, or on top of, receiving them. The actual fax images to send get defined by the <sendobj> elements, which we'll get to in a sec.

Asking the other side for pages happens when you include <rxpoll> inside <faxsend>. That can go along with <sendobj> or replace it. One <sendobj> (at a minimum) or <rxpoll> element has to be there, no cap. If both show up, the media server sends its pages first and then polls the other terminal for pages ๐Ÿซถ

Since fax is its own media type, <faxsend> isn't really expected to mix with other primitives ๐Ÿฆ‹ Instead it talks fax protocols with a remote fax terminal (or gateway) and sends requested status events back to whatever invoked it. While the fax is happening, shadow variables keep track of the progress and parameters of each stage. ๐Ÿ“Š

Status events get requested by including one or more status request elements. Each one matches a stage or event in fax operation and makes a predefined event fire when it happens. The only thing getting these events is expected to be a fax control agent, so the authors made it simpler: each event comes with a predefined namelist of shadow variables, and you don't have to pick them yourself ๐Ÿงš They also say this might get revisited later to allow tailored namelists, once there's more implementation experience. Status requests apply to both sending and polling operation ๐Ÿ’œ

Attributes:

  • lclid: the identifier that a media server uses to identify itself.
  • minspeed: the minimum acceptable speed to negotiate for the operation.
  • maxspeed: the maximum speed to negotiate for the operation. This attribute is primarily for testing purposes.
  • ecm: specifies whether Error Correction Mode (ECM) is allowed to be used if supported by the remote terminal. Defaults to "true".

Events:

  • terminate: terminates the fax send operation. ๐Ÿ›‘

Shadow Variables:

  • fax.rmtid: the identifier of the remote fax terminal. ๐Ÿ“ž
  • fax.rate: the negotiated speed for the operation.
  • fax.resolution: identifies the resolution of the image. Both metric- and inch-based resolutions are defined. Metric-based resolutions are 75x75, 150x150, 204x98, 204x196, 204x391, and 408x391. Inch-based resolutions are 200x200, 300x300, 400x400, and 600x600. ๐Ÿ–ผ๏ธ
  • fax.pagesize: identifies the negotiated page size. Metric sizes are "A3", "A4", "A5", "A6", and "B4". Inch-based page sizes are "Letter" and "Legal". ๐Ÿ“„
  • fax.encoding: identifies the image encoding utilized. Valid values are "MH", "R", "MMR", and "JPEG".
  • fax.ecm: identifies whether ECM operation was used.
  • fax.pagebadlines: the number of bad lines in a page.
  • fax.objbadlines: the number of bad lines in an object.
  • fax.opbadlines: the number of bad lines in an operation.
  • fax.objuri: the objuri of the current object.
  • fax.resendcount: the number of pages resent due to errors. ๐Ÿ˜ฌ
  • fax.totalpages: the number of pages processed or stored.
  • fax.totalobjects: the count of the objects used in the operation.
  • fax.duration: the duration of the operation expressed as a duration in seconds and milliseconds (e.g., "23s250ms"). โฑ๏ธ
  • fax.result: contains the reason that caused the fax operation to complete. When the operation completes successfully, the value will be assigned "fax.success". Other values include "fax.partial", "fax.nofax", "fax.remotedisconnect", "fax.uri.access.error", and "fax.invalid.startpage". the full drama of how a fax ends ๐ŸŽฌ

The following sections describe the child elements of <faxsend>. ๐ŸŽ€

9.12.1.1. <sendobj>

<sendobj> is used to define a fax transmission. There MAY be multiple instances of the element, which will be transmitted in order. ๐Ÿ“‘

Attributes:

  • objuri: a URI that points to the fax image that will be transmitted. Mandatory.
  • startpage: the first page of a multi-page objuri to send.
  • pagecount: page count.

9.12.1.2. <hdrfooter>

<hdrfooter> describes the header/footer that a media server MAY put on pages. The header or footer may be defined as the content of the <format> child element. The <format> element is only allowed if the type attribute has a value of "header" or "footer". ๐Ÿฆ„

Attributes:

  • type: specifies whether a header or a footer should be put on pages and identifies the source of the header or footer. The following enumerated values may be used:
    • "header" indicates that the media server should put a header on pages using the contents of the <format> element.
    • "nohdr" indicates that there should be no header or footer.
    • "footer" indicates that the media server should put a footer on pages using the contents of the <format> element.
  • style: defines the style of insertion onto a fax page that a media server should use for the header or footer. Valid styles are "append", "overlay", or "replace". ๐ŸŽจ

<format> is a child of the <hdrfooter> element that defines the style format to be used for the header or footer. It uses a "C" language style format statement (as shown below) to define the contents and layout of the header or footer. It's giving printf vibes โœจ

      code    length   name              format
       %a       3     day of week       3-character abbreviation
       %d       2     date              01-31
       %m       2     month             01-12
       %y       2     year              00-99
       %Y       4     year              0000-9999
       %I       2     12 hour           01-12
       %H       2     24 hour           00-23
       %M       2     minute            00-59
       %S       2     seconds           00-59
       %p       2     AM/PM             AM or PM
       %P       2     page number       01-99
       %T       2     total pages       01-99
       %l       20    local ID (sender) 0-9, + or spaces
       %r       20    remote ID (rcvr)  0-9, + or spaces
       %%       1     percent           display % in header/ftr

9.12.1.3. <rxpoll>

<rxpoll> provides the information necessary for a receive polling operation to occur. The object(s) to be received are defined by one or more <rcvobj> elements. The <rcvobj> is defined further under the child elements of <faxrcv>. The <rxpoll> element MAY also include a description of the header/footer that a media server SHOULD put on received pages. The <hdrfooter> element and its usage is described above. ๐Ÿ”

Attributes:

  • rmtid: specifies the identifier of the remote fax terminal that is to be associated with a polling operation. A media server MUST NOT execute a polling operation unless the value of rmtid matches that of the connected remote machine. Mandatory. ๐Ÿ”’

9.12.1.4. <faxstart>

The <faxstart> element requests that an event be sent when fax operation has begun. When triggered, the following will be executed: ๐Ÿš€

<send target="source" event="fax.start"/>

9.12.1.5. <faxnegotiate>

The <faxnegotiate> element requests that an event be sent when a negotiation has been completed. Multiple events MAY be sent each time a Digital Command Signal (DCS) frame is sent or received. When triggered, the following will be executed: ๐Ÿค

   <send target="source" event="fax.negotiate"
      namelist="fax.rmtid
         fax.rate
         fax.resolution
         fax.pagesize
         fax.encoding
         fax.ecm"/>

9.12.1.6. <faxpagedone>

The <faxpagedone> element requests that an event be sent when a page has been sent or received. When triggered, the following will be executed: ๐Ÿ“ƒโœ…

   <send target="source" event="fax.pagedone"
         namelist="fax.resolution
         fax.pagesize
         fax.encoding
         fax.pagebadlines
         fax.resendcount"/>

9.12.1.7. <faxobjectdone>

The <faxobjectdone> element requests that an event be sent when an objuri has been completed. When triggered, the following will be executed: ๐ŸŽ‰

   <send target="source" event="fax.objectdone"
         namelist="fax.objuri
         fax.objbadlines
         fax.resendcount
         fax.totalpages
         fax.result"/>

9.12.1.8. <faxopcomplete>

The <faxopcomplete> element requests that an event be sent when an operation has been completed. When triggered, the following will be executed: ๐Ÿ‘‘

   <send target="source" event="fax.opcomplete"
         namelist="fax.totalpages
         fax.opbadlines
         fax.resendcount
         fax.totalobjects
         fax.duration
         fax.result"/>

9.12.1.9. <faxpollstarted>

The <faxpollstarted> element requests that an event be sent when a polling operation has started. When triggered, the following will be executed: ๐ŸŒธ

   <send target="source" event="fax.opcomplete"
         namelist="fax.rmtid
         fax.rate
         fax.resolution
         fax.pagesize
         fax.encoding
         fax.ecm"/>

9.12.2. <faxrcv> โœจ

okay so the <faxrcv> primitive is the called fax terminal's whole personality ๐Ÿ“  Usually it's all about receiving pages, but it can also send pages instead of receiving them, or on top of receiving them ๐Ÿ’… The fax objects it's going to receive get defined by the <rcvobj> elements, which we'll get to in a sec ๐Ÿซถ

A media server SHOULD send pages as a polled terminal when the <txpoll> element is included as part of <faxrcv>. That element can show up alongside <rcvobj> or instead of it. One <rcvobj> or <txpoll> element must be present, bestie ๐Ÿ”ฅ When both are there, a media server SHOULD first receive pages, and then it'll let the other terminal poll it to request pages ๐ŸŒˆ

Fax is its own distinct media type, so <faxrcv> isn't really expected to interact with other primitives ๐Ÿงš Instead, it talks to a remote fax terminal over fax protocols and sends the requested status events back to whatever invoked it ๐Ÿ’œ While fax is happening, shadow variables record the progress and parameters of each stage ๐Ÿ“Š

Status events get requested by including one or more status request elements โœจ These map to different stages or events in fax operation, and when those happen, the predefined events get sent to the invoking environment ๐Ÿ”” The only recipient of these events is expected to be a fax control agent, so requests are simplified by tying a predefined namelist of shadow variables to each event ๐ŸŽ€ This decision may be revisited to allowed tailored namelists based on further implementation experience ๐Ÿ™ˆ Status requests apply to both receiving and polling operation, so they're iconic like that ๐Ÿ‘‘

Attributes:

  • id: an optional identifier that may be referenced elsewhere for sending events to the faxrecv primitive.
  • lclid: the identifier that a media server uses to identify itself.
  • ecm: specifies whether ECM mode is allowed to be used if supported by the remote terminal. Defaults to "true".

Events:

  • terminate: terminates the fax reception operation.

Shadow Variables:

<faxrcv> supports the same set of shadow variables as <faxsend> ๐Ÿฆ‹

The following sections describe the child elements of <faxrcv>. ๐ŸŒธ

In addition to the elements defined below, <faxrcv> MAY also have the following child elements, which were defined under <faxsend>:

  • <hdrfooter>
  • <faxstart>
  • <faxnegotiate>
  • <faxpagedone>
  • <faxobjectdone>
  • <faxopcomplete>
  • <faxpollstarted>

Their meaning and usage are the same as previously defined. ๐Ÿ’–


9.12.2.1. <rcvobj>

<rcvobj> is used to define the fax objects a media server will receive ๐Ÿ“ฅ You can have multiple instances of it, and they get used in order, so no skipping ahead ๐Ÿ“

Attributes:

  • objuri: a URI that points to the location where a received image is to be stored. Mandatory.
  • maxpages: the maximum number of pages that will be stored in objuri.

9.12.2.2. <txpoll>

<txpoll> provides the info for a polling operation to happen as part of a fax receive operation ๐Ÿ” An object, or multiple objects, to be sent can be supplied by one or more <sendobj> elements ๐Ÿ“ค If there are multiple occurrences, a media server MUST select the <sendobj> element whose rmtid attribute matches that of the remote terminal. Main character energy, the right one gets picked every time ๐Ÿ‘‘

The <sendobj> element was already defined earlier as a child element of <faxsend> ๐Ÿ’… The <txpoll> element gets extended with an rmtid attribute that specifies the identifier of the remote fax terminal, and it's used to select the specific <sendobj> to send ๐ŸŽ€

A media server SHOULD put a header/footer on transmitted pages based on any <hdrfooter> element included as part of <txpoll> ๐Ÿซถ

Attributes:

  • rmtid: specifies the identifier of the remote fax terminal that is to be associated with a polling operation. A media server MUST NOT execute a polling operation unless the value of rmtid matches that of the connected remote machine. Mandatory.

10. MSML Audit Package ๐Ÿฆ‹

10.1. MSML Audit Core Package

This section describes the MSML Audit Core Package that MAY be implemented to support auditing services ๐Ÿ”

Audit requests and results can vary based on the info being audited ๐Ÿ“‹ The MSML Audit Core Package sets up the framework for sending audit requests, defines a state list, and builds audit results. The additional audit packages define package-specific state lists and the audit result content that goes with them. The additional audit packages MUST be defined within the framework specified by the Audit Core Package. It's giving structure, honestly ๐Ÿ’œ

10.1.1. <audit>

The <audit> element is an optional child element of <msml>, which MAY be used by MSML clients to perform state auditing of current media resources that are allocated and in use by the media server ๐ŸŒˆ The requested state information comes back in an MSML response โœจ

Attributes:

  • queryid: the identifier of the MSML object being queried by the MSML client. Mandatory. Supported object types: conference or connection. Wildcards are allowed.
  • statelist: a list of one or more state parameters that are being queried. Optional. If not present, the media server SHOULD return the id of the audited object only. Each object type may contain a set of states. If the "statelist" contains any state that does not match the audited object type, the request MUST be rejected ๐Ÿ™…โ€โ™€๏ธ
  • mark: in the case of an error, the value of the mark attribute from the last successfully executed element that included the mark attribute.

State Parameters:

The state parameter MUST be named using a dot-notation format "audit.X.a.b.c...", where X is the mandatory field that indicates the class name of the object (e.g., "conf" or "conn"), and "a.b.c..." is the optional field used to describe the actual name of the state parameter in a hierarchical manner ๐Ÿงฉ The wildcard "*" MAY be used as part of a state name. However, it MUST only be used in the last field of the dot-notation (e.g., "audit.conf.*" is valid, but "audit.conf.*.a" is invalid). When a wildcard is used, it's equivalent to querying all the states below the specified level ๐ŸŒธ Each field (e.g., within "a.b.c...") results in individual element names <a>, <b>, and <c> in the audit result, which contain the corresponding state value. The parent/child relationship between these elements follows the hierarchy of the state name (i.e., <c> is a child element of <b>, and <b> is a child element of <a>) ๐Ÿ‘‘

10.1.2. <auditresult>

The <auditresult> element is an optional child element of <result>, and it MUST be used by the media server to return the audit result ๐Ÿ“ฆ A specific instance of the <auditresult> element contains the state information of a single active object. So if multiple objects are within the scope of the audit request, one <auditresult> element per object MUST be present. A zero occurrence of <auditresult> means there are no active resources within the scope of the audit request ๐Ÿซ 

Attributes:

  • targetid: the identifier of a conference or connection. Mandatory. Wildcard is not allowed.

The <auditresult> may contain child elements that return additional state information, corresponding to the "statelist" attribute in the <audit> request. The child element names correspond to the fields of the state parameter name (e.g., "a.b.c..."), following the same hierarchical structure ๐Ÿงš

10.2. MSML Audit Conference Package

This section describes the MSML Audit Conference Package that MUST be implemented to support auditing of conference services ๐ŸŽช The MSML Audit Conference Package follows the framework specified by the MSML Audit Core Package. This package defines the state parameter list and audit result for conference auditing ๐Ÿ’–

10.2.1. State Parameters

All conference state parameter names MUST be prefixed by "audit.conf" ๐Ÿท๏ธ

  • confconfig: query the conference's general configuration.
  • confconfig.audiomix: query the audio mixer's general configuration in the conference.
  • confconfig.audiomix.asn: query the current ASN setting in the audio mixer.
  • confconfig.audiomix.n-loudest: query the current n-loudest setting in the audio mixer.
  • confconfig.videolayout: query the video layout's general configuration in the conference.
  • confconfig.videolayout.root: query the root window setting of the video layout.
  • confconfig.videolayout.selector: query the video stream selector setting of the video layout.
  • confconfig.controller: query who the conference controller is.
  • dialog: query the active dialog information on the conference. See MSML Audit Dialog Package for details.
  • stream: query the active stream information on the conference. See MSML Audit Stream Package for details.

10.2.2. <auditresult>

The <auditresult> attribute of "targetid" is required to indicate results for auditing a conference ๐ŸŽฏ

The <auditresult> element may optionally contain the following child elements, which return additional conference state information if the corresponding states are queried and available โœจ

10.2.2.1. confconfig

Hmm, I need to keep heading levels consistent with the depth rule I've been using, so I'll correct that below.

The <confconfig> element is used to return the general configuration state(s) of a conference, using the following attributes ๐ŸŒˆ

Attributes:

  • deletewhen: as defined by <createconference> element in MSML Conference Core Package.
  • term: as defined by <createconference> element in MSML Conference Core Package.

10.2.2.2. confconfig.audiomix

The <audiomix> element contains the general audio mixer configuration using the following attributes ๐ŸŽš๏ธ

Attributes:

  • id: as defined by <audiomix> element in MSML Conference Core Package.
  • samplerate: as defined by <audiomix> element in MSML Conference Core Package.

10.2.2.3. confconfig.audiomix.asn

The <asn> element contains the current ASN setting of an audio mixer, if ASN is enabled. The state values are included in the following attributes ๐Ÿ”Š

Attributes:

  • ri: as defined by <asn> element in MSML Conference Core Package.
  • asth: as defined by <asn> element in MSML Conference Core Package.

10.2.2.4. confconfig.audiomix.n-loudest

The <n-loudest> element contains the current n-loudest setting of the audio mixer. The state values are included in the following attributes ๐Ÿ”

Attributes:

  • n: as defined by <n-loudest> element in MSML Conference Core Package.

10.2.2.5. confconfig.videolayout

The <videolayout> element contains the general video layout configuration using the following attributes ๐ŸŽฌ

Attributes:

  • id: as defined by <videolayout> in MSML Conference Core Package.
  • type: as defined by <videolayout> in MSML Conference Core Package.

10.2.2.6. confconfig.videolayout.root

The <root> element is used to contain root window settings ๐ŸชŸ

Attributes:

  • size: as defined by <root> element in MSML Conference Core Package.
  • backgroundcolor: as defined by <root> element in MSML Conference Core Package.
  • Backgroundimage: as defined by <root> element in MSML Conference Core Package.

10.2.2.7. confconfig.videolayout.selector

Okay so the <selector> element is where all the selector settings live ๐ŸŽฌโœจ

Attributes:

  • id: as defined by <selector> element in MSML Conference Core Package.
  • method: as defined by <selector> element in MSML Conference Core Package.
  • status: as defined by <selector> element in MSML Conference Core Package.
  • blankothers: as defined by <selector> element in MSML Conference Core Package.
  • si: as defined by <selector> element in MSML Conference Core Package when selector method is "vas".
  • speakersees: as defined by <selector> element in MSML Conference Core Package when selector method is "vas".

10.2.2.8. confconfig.controller

The <controller> element is used to return the conference controller id in its content ๐Ÿ’… The conference controller is the SIP dialog that carries the <createconference> request. The return value is the MSML connection id.

10.2.2.9. dialog

If conference dialog state is queried, the audit result comes back using the <dialog> element, as specified in the MSML Audit Dialog Package ๐Ÿ“ž

10.2.2.10. stream

If conference stream state is queried, the audit result comes back using the <stream> element, as specified in the MSML Audit Stream Package ๐ŸŒŠ

10.3. MSML Audit Connection Package

This section describes the MSML Audit Connection Package, which MAY be implemented to support auditing connection services ๐Ÿฆ‹ It follows the framework specified by the MSML Audit Core Package, and it defines the state parameter list and audit result for connection auditing.

10.3.1. State Parameters

Connection state parameter names are prefixed by "audit.conn" ๐ŸŽ€

  • sipdialog: queries the identifier of the SIP dialog with which the connection is associated.
  • sipdialog.localseq: queries one of the SIP dialog states, the local sequence number.
  • sipdialog.remoteseq: queries one of the SIP dialog states, the remote sequence number.
  • sipdialog.localURI: queries one of the SIP dialog states, the local URI.
  • sipdialog.remoteURI: queries one of the SIP dialog states, the remote URI.
  • sipdialog.remotetarget: queries one of the SIP dialog states, the remote target.
  • sipdialog.routeset: queries one of the SIP dialog states, the route set.
  • localsdp: queries the local SDP body of the connection.
  • remotesdp: queries the remote SDP body of the connection.
  • dialog: queries the active dialog information on the connection. See MSML Audit Dialog Package for details.
  • stream: queries the active stream information on the connection. See MSML Audit Stream Package for details.

10.3.2. <auditresult>

The <auditresult> attribute targetid MUST specify a connection identifier for a connection result ๐Ÿ”ฅ

The <auditresult> element MAY contain the following child elements optionally, to return extra connection state information if the matching states are queried and available ๐Ÿ’–

10.3.2.1. sipdialog

The <sipdialog> element contains the associated SIP dialog information. The SIP dialog ID information is returned using the following attributes โœจ

Attributes:

  • callid: call-ID value as defined in [n1]. Mandatory.
  • localtag: local-tag value as defined in [n1]. Mandatory.
  • remotetag: remote-tag value as defined in [n1]. Mandatory.

This element can contain the following child elements optionally, to return additional SIP dialog state information to the client if the matching states are queried and available ๐Ÿซถ

10.3.2.2. sipdialog.localseq

The <localseq> element contains the local sequence number. The local sequence number is one of the SIP dialog states as defined in [n1] ๐ŸŒธ

10.3.2.3. sipdialog.remoteseq

The <remoteseq> element contains the remote sequence number. The remote sequence number is one of the SIP dialog states as defined in [n1] ๐ŸŒธ

10.3.2.4. sipdialog.localuri

The <localuri> element contains the local URI value. The local URI is one of the SIP dialog states as defined in [n1] ๐Ÿงš

10.3.2.5. sipdialog.remoteuri

The <remoteuri> element contains the remote URI value. The remote URI is one of the SIP dialog states as defined in [n1] ๐Ÿงš

10.3.2.6. sipdialog.remotetarget

The <remotetarget> element contains the remote target value. The remote target is one of the SIP dialog states as defined in [n1] ๐ŸŽฏ

10.3.2.7. sipdialog.routeset

The <routeset> element contains the route-set value, which is an ordered list of URIs separated by comma. The route set is one of the SIP dialog states as defined in [n1] ๐Ÿ›ฃ๏ธ

10.3.2.8. localsdp

The <localsdp> element contains the local SDP body ๐ŸŽถ

10.3.2.9. remotesdp

The <remotesdp> element contains the remote SDP body ๐ŸŽถ

10.3.2.10. dialog

If the connection dialog state is queried, the audit result returns the queried information using the <dialog> element, as specified in the MSML Audit Dialog Package ๐Ÿ“ž

10.3.2.11. stream

If the connection stream state is queried, the audit result returns the queried information using the <stream> element, as specified in the MSML Audit Stream Package ๐ŸŒŠ

10.4. MSML Audit Dialog Package

This section describes the MSML Audit Dialog Package, which MAY be implemented to support auditing dialogs ๐Ÿ’œ It follows the framework specified by the MSML Audit Core Package.

The MSML Audit Dialog Package must be used together with either the MSML Audit Conference Package or MSML Audit Connection Package, since dialogs apply to conferences or connections. Bestie, that's the whole point ๐Ÿ™ˆ

10.4.1. State Parameters

Dialog state parameter names are prefixed by dialog. Since this package must be used together with the MSML Audit Conference Package or MSML Audit Connection Package, the complete dialog state name must be prefixed by "audit.conf.dialog" or "audit.conn.dialog", depending on the context in which the dialog state is queried ๐Ÿงฉ

  • dialog: queries the number of active dialog(s) running on the target (a conference or connection). Basic dialog information will be returned.
  • dialog.duration: queries the amount of time a dialog has been running.
  • dialog.primitive: queries the media primitive currently being executed by the dialog.
  • dialog.controller: queries the dialog controller.

10.4.2. <dialog>

The <dialog> element is a child element of <auditresult>, and it contains the active dialog information on the target identified by the attribute targetid of the <audioresult> element ๐ŸŽ€

Basic dialog information is returned using the following attributes.

Attributes:

  • src: as defined by the <dialogstart> element in the MSML Dialog Core Package.
  • type: as defined by the <dialogstart> element in the MSML Dialog Core Package. Mandatory.
  • name: as defined by the <dialogstart> element in the MSML Dialog Core Package. Mandatory.

This element may contain the following child elements optionally, to return additional dialog information if the matching state parameter has been queried and the state value is available ๐Ÿ’…

10.4.2.1. <duration>

Hold up, the <duration> element returns how long a dialog has been running on the specified target โฑ๏ธ The duration value goes in the element content, and it is a positive integer value in units of seconds.

10.4.2.2. <primitive>

The <primitive> element returns the currently active media primitive in its content. The active media primitive is the primitive that is being executed right now ๐ŸŽฌ Possible return values are play, dtmf, collect, dtmfgen, tonegen, record, or none.

10.4.2.3. <controller>

The <controller> element returns the dialog controller id in its content. The dialog controller is the SIP dialog that carries the <dialogstart> request. The returned value is the MSML connection id ๐Ÿ‘‘

10.5. MSML Audit Stream Package

This section describes the MSML Audit Stream Package, which MAY be implemented to support auditing streams ๐ŸŒˆ It follows the framework specified by the MSML Audit Core Package.

The MSML Audit Stream Package MUST be used together with either the MSML Audit Conference Package or the MSML Audit Connection Package, since streams apply between conferences, between connections, or between conferences and connections. No cap, it's a must ๐Ÿ’€

10.5.1. State Parameters

Stream state parameter names are prefixed by stream. Since this package must be used together with the MSML Audit Conference Package or MSML Audit Connection Package, the complete stream state name must be prefixed by "audit.conf.stream" or "audit.conn.stream", depending on the context in which the stream state is queried ๐Ÿฆ‹

  • stream: queries the number of active streams created on the audited object. Basic stream information will be returned.
  • stream.clamp: queries the clamping status.
  • stream.gain: queries the gain control information.
  • stream.visual: queries the visual setting.

10.5.2. <stream>

The <stream> element is a child element of <auditresult>, and it contains the active stream information on the target identified by the attribute targetid of the <audioresult> element ๐ŸŒŠ

Basic stream information is returned using the following attributes.

Attributes:

  • joinwith: an identifier of either a connection or a conference with which the audited object is joined. Mandatory. Wildcard is not allowed.
  • media: as defined by the <stream> element in the MSML Conference Core Package. Mandatory.
  • dir: direction of stream, from the audited target's perspective, "from" or "to". Mandatory.
  • compressed: as defined by the <stream> element in the MSML Conference Core Package.
  • display: as defined by the <stream> element in the MSML Conference Core Package.
  • override: as defined by the <stream> element in the MSML Conference Core Package.
  • preferred: as defined by the <stream> element in the MSML Conference Core Package.

This element MAY contain the following child elements that optionally return additional stream information, if the corresponding state parameter is queried and the state value is available โœจ

10.5.2.1. <clamp>

The <clamp> element is included if stream clamping is active. The currently active clamping state values are returned using the attributes as defined by the <clamp> element in the MSML Conference Core Package ๐ŸงŠ

10.5.2.2. <gain>

The <gain> element is included if stream gain is active. The current gain control state values are returned using the attributes as defined by the <gain> element in the MSML Conference Core Package ๐Ÿ”Š

10.5.2.3. <visual>

The <visual> element is included if stream visual display is active. The current visual display settings are returned using the attributes as defined by the <visual> element in the MSML Conference Core Package ๐Ÿ‘€

11. Response Codes โœจ

okay so response codes are how the server tells you what happened, whether it went great or totally flopped ๐Ÿ’€. when something fails, the right code and description must get passed back to whatever invoked it, no exceptions bestie ๐Ÿซถ

these codes show up as the value of the response attribute on the <result> element. some of them can also ride along inside a namelist on an "msml.dialog.exit" event when an MSML dialog fails ๐Ÿฆ‹

Here's the full lineup:

Informational (1xx)

   Reserved for future use

Success (200)

   200  OK

Request Error (4xx)

   400  Bad Request
   401  Unknown Element
   402  Unsupported Element
   403  Missing mandatory element content
   404  Forbidden element content
   405  Invalid element content
   406  Unknown attribute
   407  Attribute not supported
   408  Missing mandatory attribute
   409  Forbidden attribute is present

   410  Invalid attribute value

   420  Unsupported media description language
   421  Unknown media description language
   422  Ambiguous request (both URI and inline description)
   423  External document fetch error
   424  Syntax error in foreign language
   425  Semantic error in foreign language
   426  Unknown error executing foreign language

   430  Object does not exist
   431  Object instance name already used
   432  Conference name already in use
   433  reserved
   434  External document fetch error

   440  Cannot join objects of the specified class
   441  Objects have incompatible media types
   442  reserved
   443  reserved
   444  Number of media inputs exceeded
   450  Objects have incompatible media formats
   451  Incompatible media stream format

Server Error (5xx)

   500  Internal media server error
   503  Service Unavailable
   510  Not in service
   511  Service Unavailable
   520  No resource to fulfill request
   521  Internal limit exceeded

12. MSML Conference Examples ๐ŸŽ€

these examples zoom in on the MSML Conference Core Package, which is what a control agent (CA) uses to steer services on a media server (MS) ๐Ÿงš they show how the SIP signaling that sets up the media sessions lines up with the MSML service control commands. to keep things short, only the MSML message content is shown. the examples assume the CA and MS use the IPv4 address and UDP port number of the audio stream (on the MS) to identify the MSML connection ๐Ÿ’–

12.1. Establishing a Dial-In Conference ๐Ÿ“ž

   UA                   Control Agent             Media Server
   |                         |                           |
   |                         |        INVITE F1          |
   |                         |-------------------------->|
   |                         |           200 F2          |
   |                         |<--------------------------|
   |                         |           ACK F3          |
   |                         |-------------------------->|
   |                         |                           |
   |                         |     createconference> F4  |
   |                         |-------------------------->|
   |                         |           200 F5          |
   |                         |<--------------------------|
   |    INVITE (SDP UA) F6   |                           |
   |------------------------>|                           |
   |                         |      INVITE (SDP UA) F7   |
   |                         |-------------------------->|
   |                         |        200 (SDP MS) F8    |
   |                         |<--------------------------|
   |                         |           ACK F9          |
   |                         |-------------------------->|
   |     200 (SDP MS) F10    |                           |
   |<------------------------|                           |
   |        ACK F11          |                           |
   |------------------------>|                           |
   |                         |     <dialogstart> F12     |
   |                         |-------------------------->|
   |                         |           200 F13         |
   |                         |<--------------------------|
   |                         |    HTTP interactions F14  |
   |                         |<------------------------->|
   |                         |  <event>(dialog.exit) F15 |
   |                         |<--------------------------|
   |                         |         <join> F16        |
   |                         |-------------------------->|
   |                         |           200 F17         |
   |                         |<--------------------------|
   |         ...             |            ...            |
   |                         |                           |
   |                         |     <dialogstart> F18     |
   |                         |-------------------------->|
   |                         |           200 F19         |
   |                         |-------------------------->|
   |                         |    HTTP interactions F20  |
   |                         |<--------------------------|
   |                         |  <event>(dialog.exit) F21 |
   |                         |-------------------------->|
   |         ...             |            ...            |
   |                         |                           |

Steps 1-3 set up an MSML control channel for the conference ๐Ÿ”. you could also already have a control channel running that handles every CA/MS interaction, since one channel per conference is just one possible setup. right now MSML rides on SIP INFO requests and responses over that SIP dialog. there's a proposal to use that same message exchange to set up a TCP channel for MSML, kind of like how the Media Resource Control Protocol v2 (MRCPv2) does it. that approach would need a request identifier added to the <msml> element so requests and responses can be matched up. today it leans on the SIP INFO request and response for that job. the MSML messages below don't specify a transport, but they assume the request/response correlation comes from the transport messages โœจ

Step 4: create a conference that mixes the loudest two speakers and reports those speakers back to the control agent every 10 seconds ๐ŸŽค. the media server will automatically end any remaining media sessions, delete the conference and its associated resources, and do the same when the control channel goes down ๐Ÿ’€

   <msml version="1.1">
      <createconference name="exampleConf" deletewhen="nocontrol">
          <audiomix>
             <n-loudest n="3"/>
             <asn ri="10s"/>
          </audiomix>
      </createconference>
   </msml>

Step 5: the conference got created successfully ๐ŸŽ‰

   <msml version="1.1">
      <result response="200"/>
   </msml>

Steps 6-11: standard 3PCC setup for a user-initiated media session to a media server ๐Ÿ“ฑ. this is basically the equivalent of a dial-in conference participant. the "To:" header the MS sent back in the 200 response to Step F8 looked like this:

   To: <sip:msml@ms.example.com>;tag=jd87dfg4h

Step 12: start an initial dialog with the participant to ask for their name, which conference they want, and so on ๐Ÿ™‹โ€โ™€๏ธ. the dialog wraps up by telling the participant they're joining the conference. if this isn't the first participant, the dialog can also announce who else is already there ๐Ÿ‘ฏ

   <msml version="1.1">
      <dialogstart target="conn:jd87dfg4h" name="12345"
          type="application/vxml+xml"
          src="http://server.example.com/scripts/initial.vxml"/>
   </msml>

Step 13: the dialog started successfully, and the dialog identifier comes back in the response ๐Ÿฆ‹

   <msml version="1.1">
      <result response="200"/>
      <dialogid>conn:jd87dfg4h/dialog:12345</dialogid>
   </msml>

Step 14: a sequence of HTTP VoiceXML dialog interactions happens here ๐Ÿ—ฃ๏ธ

Step 15: the VoiceXML browser exits, but the participant doesn't get disconnected ๐Ÿ‘€. if a namelist had been set inside the VoiceXML <exit> element, it would be included in the <event> sent to the CA ๐Ÿ“จ

   <msml version="1.1">
      <event name="msml.dialog.exit"
             id="conn:jd87dfg4h/dialog:12345"/>
   </msml>

Step 16: join the participant to the conference, and automatically adjust the volume of their outgoing audio to a target level of -20 dBm0 ๐Ÿ”Šโœจ

   <msml version="1.1">
      <join id1="conn:jd87dfg4h" id2="conf:exampleConf">
         <stream media="audio" dir="from-id1">
             <gain agc="true" tgtlvl="-20"/>
         </stream>
         <stream media="audio" dir="to-id1"/>
   </msml>

Step 17: they're successfully joined to the conference ๐Ÿฅณ

   <msml version="1.1">
      <result response="200"/>
   </msml>

Steps 6 through 17 get repeated for the second participant ๐Ÿ‘ญ

Step 18: play a join tone or message to announce the new participant to the conference ๐Ÿ””

   <msml version="1.1">
      <dialogstart target="conf:exampleConf"
          type="application/vxml+xml"
          src="http://server.example.com/scripts/joinmsg.vxml"/>
   </msml>

Step 19: the dialog started successfully and the dialog identifier comes back. since no name attribute was given in <dialogstart>, the media server assigned its own unique identifier ๐Ÿช„

   <msml version="1.1">
      <result response="200"/>
      <dialogid>conf:ExampleConf/dialog:j6fs8745</dialogid>
   </msml>

Step 20: HTTP VoiceXML dialog interaction(s) go down here ๐Ÿ’ฌ

Step 21: the VoiceXML browser exits ๐Ÿ‘‹

   <msml version="1.1">
      <event name="msml.dialog.exit"
             id="conf:ExampleConf/dialog:j6fs8745"/>
   </msml>

Steps 6 through 21 get repeated for the third and every later participant ๐ŸŒˆ๐Ÿ’–

12.2. Example of a Sidebar Audio Conference ๐ŸŽง

okay so this example picks up right where the last one left off, with the conference already set up ๐Ÿ’… Now we make a sidebar conference that hears the main conference as a whisper ๐Ÿคซ Three participants get moved into the sidebar. After a bit, they get sent back to the main conference and the sidebar is deleted. bye sidebar ๐Ÿ‘‹

Step 1 is where the sidebar gets created ๐ŸŽ€ It's joined half-duplex to the main conference, and a manual gain object goes into the media stream. Then the three participants get moved from the main conference over to the sidebar. Not shown here, but a CA could put the "mark" attribute in each element so it can recover if something goes wrong halfway through a transaction ๐Ÿงš

<msml version="1.1">
   <createconference name="sidebarConf"
                     deletewhen="nomedia">
       <audiomix/>
   </createconference>
   <join id1="conf:sidebarConf" id2="conf:exampleConf">
       <stream media="audio" dir="to-id1">
           <gain amt="-20"/>
       </stream>
   </join>
   <unjoin id1="conn:gs5s4-1" id2="conf:exampleConf"/>
   <join id1="conn:gs5s4-1" id2="conf:sidebarConf"/>
   <unjoin id1="conn:hd764gr9-2" id2="conf:exampleConf"/>
   <join id1="conn:hd764gr9-2" id2="conf:sidebarConf"/>
   <unjoin id1="conn:h37frdvgs65-3" id2="conf:exampleConf"/>
   <join id1="conn:h37frdvgs65-3" id2="conf:sidebarConf"/>
</msml>

Step 2 is the MS saying "sidebar created and everyone's in!" โœจ 200 means slay ๐Ÿ’–

<msml version="1.1">
   <result response="200"/>
</msml>

Step 3 is when the sidebar chat is done and everyone gets rejoined to the main conference ๐ŸŒธ The MS destroys the sidebar on its own once the last media stream is removed, which is what was set up when the sidebar got created. so tidy ๐Ÿงน

<msml version="1.1">
   <unjoin id1="conn:gs5s4-1" id2="conf:sidebarConf"/>
   <join id1="conn:gs5s4-1" id2="conf:exampleConf"/>
   <unjoin id1="conn:hd764gr9-2" id2="conf:sidebarConf"/>
   <join id1="conn:hd764gr9-2" id2="conf:exampleConf"/>
   <unjoin id1="conn:h37frdvgs65-3" id2="conf:sidebarConf"/>
   <join id1="conn:h37frdvgs65-3" id2="conf:exampleConf"/>
</msml>

Step 4 is the final confirmation: everyone's back in the main conference and the sidebar is gone ๐Ÿฆ‹

<msml version="1.1">
   <result response="200"/>
</msml>

12.3. Example of Removing a Conference ๐Ÿซถ

this one assumes a conference set up like the first example, with an MSML control channel that belongs to that conference, and the conference is set to get deleted when that channel goes away (this is done using SIP) ๐Ÿ“ž

Steps 1-2: the CA sends a SIP BYE for the dialog that set up the conference control channel ๐Ÿ‘‹

Steps 3-6: the MS starts ending the media sessions for everyone still hanging out in the conference ๐Ÿƒโ€โ™€๏ธ

The MS deletes the conference and frees up all its resources once the last participant is gone ๐Ÿงน๐Ÿ’œ


12.4. Example of Modifying Video Layout ๐ŸŽฌ

so say a conference named "example" gets created with these mixer descriptions. picture a 2x2 grid of boxes, numbered 1 through 4 ๐Ÿ“

+---+---+
| 1 | 2 |
+---+---+
| 3 | 4 |
+---+---+
<createconference name="quad-split">
   <audiomix>
      <n-loudest n="3"/>
      <asn ri="10s"/>
   </audiomix>
   <videolayout>
      <root size="CIF" background="white" />
      <selector id="default" method="vas" si="500ms">
         <region id="1" left="0" top="0" relativesize="1/4"/>
      </selector>
      <region id="2" left="50%" top="0" relativesize="1/4"/>
      <region id="3" left="0%" top="50%" relativesize="1/4">
      <region id="4" left="50%" top="50%" relativesize="1/4"/>
   </videolayout>
</createconference>

next, this one changes the video window to QCIF and sets the background back to the default "black" ๐Ÿ–ค

<modifyconference id="conf:example">
   <videolayout>
      <root size="4CIF"/>
   </videolayout>
</modifyconference>

the relative location of the regions doesn't change ๐Ÿ’… but the sizes of the regions do, since they're relative to the size of the root window. so the layout looks exactly the same, just half the size โœจ

and this one freezes the video in region "2" without touching any of its other attributes ๐ŸงŠ

<modifyconference id="conf:example">
   <videolayout>
      <region id="2" left="50%" top="0" relativesize="1/4"
                     freeze="true"/>
   </videolayout>
</modifyconference>

13. MSML Dialog Examples ๐ŸŒˆ

these examples focus on the MSML Dialog Base Package and the MSML Dialog Group Package ๐Ÿงš

13.1. Announcement ๐Ÿ“ข

this is a simple announcement scenario ๐ŸŽ€ two recorded audio files get played in order, then some generated speech, then a variable. the results get reported once the media generation is done โœ…

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <dialogstart target="conn:12345" name="12345">
      <play>
         <audio uri="file://clip1.wav"/>
         <audio uri="http://host1/clip2.wav"/>
         <tts uri="http://host2/text.ssml"/>
         <var type="date" subtype="mdy" value="20030601"/>
      </play>
      <send target="source" event="done" namelist="play.amt
                                         play.end"/>
   </dialogstart>
</msml>

13.2. Voice Mail Retrieval ๐Ÿ“ผ

here's a voice mail retrieval example ๐Ÿ’– it plays a message, and the user can pause and resume it by pressing '5' to toggle. the whole thing ends when the play finishes or the user presses '#' ๐Ÿ™ˆ

while the message is playing, the user can skip forward and backward through it, and rewind back to the beginning โช

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
  <dialogstart target="conn:12345" name="12345">
   <group topology="parallel">
      <play>
         <audio uri="file://message.wav"/>
         <playexit>
            <send target="group" event="terminate"/>
         </playexit>
      </play>
      <dtmf iterate="forever">
         <pattern digits="5">
            <send target="play" event="toggle-state"/>
         </pattern>
         <pattern digits="6">
            <send target="play" event="forward"/>
         </pattern>
         <pattern digits="7">
            <send target="play" event="backward"/>
         </pattern>
         <pattern digits="8">
            <send target="play" event="restart"/>
         </pattern>
         <pattern digits="#">
            <send target="play" event="terminate"/>
         </pattern>
      </dtmf>
   </group>
 </dialogstart>
</msml>

13.3. Play and Record ๐ŸŽ™๏ธ

this one is the big boss of the examples ๐Ÿ˜ค it plays a prompt and records, and it uses voice activity and DTMF detection to decide what happens next. any DTMF input or voice activity barges the play and starts the record ๐Ÿ”ฅ but if the prompt got barged with the '#' digit, the record terminates without starting at all ๐Ÿšซ

when the play ends, it sends a starttimer event to the VAD so it can watch for an initial silence ๐Ÿ‘‚ if the VAD detects 3 seconds of initial silence, the recording terminates without starting โน๏ธ

once the recording has resumed (based on voice detection), it can end in a few ways. it ends after 5 seconds of silence, or after 60 seconds have passed, or if a '#' key gets recognized ๐Ÿ”š every bit of this behaviour can be changed by tweaking what gets recognized and which events get sent ๐Ÿ› ๏ธ the following example uses the MSML Dialog Group Package ๐Ÿ’…

<?xml version="1.0" encoding="UTF-8"?>
<msml  version="1.1">
 <dialogstart target="conn:12345" name="12345">
   <group topology="parallel">
      <play>
         <audio uri="file://prompt.wav"/>
         <playexit>
            <send target="vad" event="starttimer"/>
         </playexit>
      </play>
      <dtmf>
         <pattern digits="#">
            <send target="record" event="terminate.termkey"/>
         </pattern>
         <detect>
            <send target="play" event="terminate"/>
         </detect>
      </dtmf>
      <vad>
         <voice len="10ms">
            <send target="play" event="terminate"/>
            <send target="record" event="resume"/>
         </voice>
         <silence len="3s">
            <send target="record" event="nospeech"/>
         </silence>
         <tsilence len="5s">
            <send target="record" event="terminate.finalsilence"/>
         </tsilence>
      </vad>
      <record initial="suspend" maxtime="60s"
              dest="file://record.wav" format="g729">
         <recordexit>
            <send target="group" event="terminate"/>
         </recordexit>
      </record>
      <groupexit>
         <send target="source" event="done"
               namelist="record.len record.end"/>
      </groupexit>
   </group>
 </dialogstart>
</msml>

the next one does the exact same thing, as described above, but with the MSML Dialog Base Package instead ๐Ÿง it uses the <record> composite mechanism for the play and record operation, so it's way more compact ๐Ÿ’œ

<?xml version="1.0" encoding="UTF-8"?>
<msml  version="1.1">
 <dialogstart target="conn:12345" name="12345">
   <record prespeech="3s" postspeech="5s" maxtime="60s" termkey="#"
              dest="file://record.wav" format="g729">
      <play barge="true">
         <audio uri="file://prompt.wav"/>
      </play>
      <recordexit>
         <send target="source" event="done"
               namelist="record.len record.end"/>
      </recordexit>
   </record>
 </dialogstart>
</msml>

13.4. Speech Recognition ๐Ÿ—ฃ๏ธ

this simple example asks the user to say the name of a city, then sends back the result ๐ŸŒ

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
 <dialogstart target="conn:12345" name="12345">
   <group topology="parallel">
      <play>
         <audio uri="file://prompt.wav"/>
      </play>
      <speech>
         <grammar version="1.0">
            <rule id="city" scope="public">
               <item>
                  <one-of>
                     <item>vancouver</item>
                     <item>new york</item>
                     <item>london</item>
                  </one-of>
               </item>
            </rule>
            <match>
               <send target="group" event="terminate"/>
            </match>
         </grammar>
         <noinput>
            <send target="group" event="terminate"/>
         </noinput>
         <nomatch>
            <send target="group" event="terminate"/>
         </nomatch>
      </speech>
      <groupexit>
         <send target="source" event="done"
                       namelist="speech.end speech.results"/>
      </groupexit>
   </group>
 </dialogstart>
</msml>

13.5. Play and Collect ๐ŸŽ€

okay so this one prompts a user to enter 4 DTMF digits, ended by the '#' key (that's the xxxx# you'll see below) ๐Ÿ’… the prompt can be barged, and the user gets 10 seconds to start entering input or no input gets indicated ๐Ÿซถ

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
 <dialogstart target="conn:12345" name="12345">
   <group topology="parallel">
      <play>
         <audio uri="file://prompt.wav"/>
         <playexit>
            <send target="dtmf" event="starttimer"/>
         </playexit>
      </play>
      <dtmf fdt="10s" idt="16s">
         <pattern digits="xxxx#">
            <send target="group" event="terminate"/>
         </pattern>
         <detect>
            <send target="play" event="terminate"/>
         </detect>
         <noinput>
            <send target="group" event="terminate"/>
         </noinput>
         <nomatch>
            <send target="group" event="terminate"/>
         </nomatch>
      </dtmf>
      <groupexit>
         <send target="source" event="done"
               namelist="dtmf.digits dtmf.end"/>
      </groupexit>
   </group>
 </dialogstart>
</msml>

The following does the exact same thing as above, but using the MSML Dialog Base Package and the <collect> composite mechanism for the play and collect operation โœจ

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
 <dialogstart target="conn:12345" name="12345">

   <collect fdt="10s" idt="16s">
      <play barge="true">
         <audio uri="file://prompt.wav"/>
      </play>
      <pattern digits="xxxx#">
         <send target="source" event="done"
               namelist="dtmf.digits dtmf.end"/>
      </pattern>
      <noinput>
         <send target="source" event="done"
               namelist="dtmf.end"/>
      </noinput>
      <nomatch>
         <send target="source" event="done"
               namelist="dtmf.end"/>
      </nomatch>
   </collect>
 </dialogstart>
</msml>

13.6. User Controlled Gain ๐ŸŒˆ

this one is so cool ๐Ÿ˜ญ it shows how nesting groups can make an arbitrary full-duplex media control. DTMF gets detected on media flowing in one direction and is used to adjust the gain on media flowing the opposite way. On top of that, the stream used for DTMF detection has DTMF removed and its gain auto-adjusted before it leaves the group. This widget could sit between a conference participant and a conference mixer ๐Ÿฆ‹

<?xml version="1.0" encoding="UTF-8"?>
<msml  version="1.0">
 <dialogstart target="conn:12345" name="12345">
   <group topology="fullduplex">
      <group topology="parallel">
         <dtmf>
            <pattern digits="1" iterate="forever">
               <send target="gain" event="louder"/>
            </pattern>
            <pattern digits="2" iterate="forever">
               <send target="gain" event="softer"/>
            </pattern>
         </dtmf>
         <group topology="serial">
            <clamp/>
            <agc tgtlvl="0"/>
         </group>
      </group>
      <gain amt="0" incr="5"/>
   </group>
 </dialogstart>
</msml>

14. MSML Audit Examples โœจ

these examples cover the MSML Audit Conference Package and the MSML Audit Connection Package, and how they work together with the MSML Audit Dialog Package or/and the MSML Audit Stream Package ๐Ÿ”ฅ

14.1. Audit All Conferences ๐Ÿ‘‘

this one audits every active conference on the media server and asks for the conference configurations ๐Ÿ’œ

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <audit queryid="conf:*" statelist="audit.conf.confconfig.*"/>
</msml>

the result below assumes two conferences are allocated by the media server. Conference "conf:1" has both an audio mixer (with ASN enabled) and a video layout (vas) created, while conference "conf:2" only has an audio mixer created, with ASN disabled ๐ŸŒธ

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <result response="200">
      <auditresult targetid="conf:1">
         <confconfig deletewhen="nocontrol" term="true">
            <audiomix id="audiomix1">
               <asn ri="5s"/>
               <n-loudest n="16"/>
            </audiomix>
              <videolayout id="videolayout1"
                           type="text/msml-basic-layout">
                 <selector id="selector1" method="vas" si="5s"
                           speakersees="current">
                    <root size="CIF"/>
                 </selector>
              </videolayout>
            <controller>conn:1234</controller>
         </confconfig>
      </auditresult>
      <auditresult targetid="conf:2">
         <confconfig deletewhen="nomedia" term="true">
            <audiomix id="audiomix2">
               <n-loudest n="1"/>
            </audiomix>
            <controller>conn:1234</controller>
         </confconfig>
      </auditresult>
   </result>
</msml>

14.2. Audit Conference Dialogs ๐Ÿงš

this example audits the active dialogs on one specific conference. The request asks for every dialog state that's available ๐Ÿ“

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <audit queryid="conf:1" statelist="audit.conf.dialog.*"/>
</msml>

the example result assumes one dialog is running on conference "conf:1". It's been going for 60 seconds, and right now it's doing a record operation ๐ŸŽ™๏ธ

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <result response="200">
      <auditresult targetid="conf:1">
         <dialog name="sample">
            <duration>60</duration>
            <primitive>record</primitive>
            <controller>conn:1234</controller>
         </dialog>
      </auditresult>
   </result>
</msml>

14.3. Audit Conference Streams ๐Ÿฆ‹

this request audits the active streams on one specific conference and asks for every stream state that's available ๐Ÿซถ

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <audit queryid="conf:1" statelist="audit.conf.stream.*"/>
</msml>

the example result assumes three audio participants in the conference. Connection "conn:1234" is a talk-listen participant with both clamp and gain control enabled. Connection "conn:1235" is talk-only. Connection "conn:1236" is listen-only with automatic gain control enabled ๐ŸŽง

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <result response="200">
      <auditresult targetid="conf:1">
         <stream joinwith="conn:1234" media="audio" dir="to">
            <clamp dtmf="true" tone="false"/>
            <gain amt="-10"/>
         </stream>
         <stream joinwith="conn:1234" media="audio" dir="from">
            <gain amt="10"/>
         </stream>
         <stream joinwith="conn:1235" media="audio" dir="to">
         </stream>
         <stream joinwith="conn:1236" media="audio" dir="from">
            <gain agc="true" tgtlvl="0" maxgain="10"/>
         </stream>
      </auditresult>
   </result>
</msml>

14.4. Audit All Connections ๐Ÿ’…

this request audits every active connection on the media server. No extra state gets queried ๐ŸŒˆ

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <audit queryid="conn:*"/>
</msml>

the example result assumes five connections are currently allocated by the media server ๐Ÿ’–

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <result response="200">
      <auditresult targetid="conn:1230"/>
      <auditresult targetid="conn:1231"/>
      <auditresult targetid="conn:1232"/>
      <auditresult targetid="conn:1233"/>
      <auditresult targetid="conn:1234"/>
   </result>
</msml>

14.5. Audit Connection Dialogs ๐ŸŒธ

this request audits the active dialogs on one specific connection. No extra dialog state is queried โญ

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <audit queryid="conn:1234" statelist="audit.conn.dialog"/>
</msml>

the example result assumes three dialogs running on that connection ๐Ÿงš

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <result response="200">
      <auditresult targetid="conn:1234">
         <dialog name="sample1"/>
         <dialog name="sample2"/>
         <dialog name="sample3"/>
      </auditresult>
   </result>
</msml>

14.6. Audit Connection Streams ๐Ÿซถ

this request audits the active streams on one specific connection. No extra stream state is queried ๐Ÿ’œ

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <audit queryid="conn:1234" statelist="audit.conn.stream"/>
</msml>

the example result assumes three audio streams between the target connection and other MSML objects. One is a bidirectional stream between the target connection and a conference, and the other two are unidirectional streams between two other connections ๐Ÿฆ‹

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <result response="200">
      <auditresult targetid="conn:1234">
         <stream joinwith="conf:1" media="audio" dir="to"/>
         <stream joinwith="conf:1" media="audio" dir="from"/>
         <stream joinwith="conn:1235" media="audio" dir="to"/>
         <stream joinwith="conn:1236" media="audio" dir="from"/>
      </auditresult>
   </result>
</msml>

14.7. Audit Connection with Selective States โœจ

okay so this one is an audit of a single connection ๐Ÿ” bestie wants to see its SIP dialog ID and the SDP info, and you ask for just those pieces. super efficient, no extra baggage ๐Ÿ’…

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <audit queryid="conn:1234" statelist="audit.conn.sipdialog
      audit.conn.localsdp audit.conn.remotesdp"/>
</msml>

<?xml version="1.0" encoding="UTF-8"?>
<msml version="1.1">
   <result response="200">
      <auditresult targetid="conn:1234">
         <sipdialog callid="ABCD@10.0.0.10:5060"
                    localtag="sdfjsiodf"
                    remotetag="zvnmviuhd8"/>
         <localsdp>
            v=0
            o=- 31691 31691 IN IP4 ms5mpc11.lab.radisys.com
            s=media server session
            t=0 0
            m=audio 33794 RTP/AVP 0
            c=IN IP4 10.3.5.111
            a=rtpmap:0 PCMU/8000
            a=sendrecv
            m=video 32770 RTP/AVP 34
            c=IN IP4 10.3.5.11
            b=AS:48
            a=rtpmap:34 H263/90000
            a=fmtp:34 CIF=1
            a=sendrecv
         </localsdp>
         <remotesdp>
            v=0
            o=- 12345 12345 IN IP4 10.0.0.88
            s=RadiSys SIP Media Server session
            t=0 0
            c=IN IP4 10.0.0.126
            b=AS:128
            m=audio 10000 RTP/AVP 0
            a=rtpmap:0 PCMU/8000
            a=ptime:20
            a=sendrecv
            m=video 10002 RTP/AVP 34
            a=rtpmap:34 H263/90000
            a=fmtp:34 CIF=1
            a=sendrecv
         </remotesdp>
      </auditresult>
   </result>
</msml>

15. Future Work ๐Ÿ”ฎ

okay so these are the things that might show up in future versions of this document, no promises yet ๐Ÿงš the big ones:

  • Ability for MSML clients to audit or query the media server for the supported set of MSML packages and profiles ๐Ÿ‘€
  • Ability to version MSML packages and profiles, plus a naming scheme for MSML extension packages ๐Ÿ’œ

16. XML Schema ๐ŸŽ€

the MSML spec is a whole set of XML schemas ๐Ÿซถ you can use all of them together, or just a subset for each MSML package. the sections below define a complete set covering every MSML package, so it's giving full coverage ๐Ÿ’–

each package has a single schema file, <package-name>-datatypes.xsd, which other extended packages can include. every package can also optionally have another schema file, <package_name>.xsd, that you can use directly to build or validate MSML scripts for that package โœจ

the complete MSML schema, msml.xsd, pulls in all the individual MSML packages ๐ŸŒˆ

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-conf-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-base-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-transform-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-group-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-speech-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-fax-detect-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-fax-sendrecv-
             datatypes.xsd"/>
 <xs:include schemaLocation="msml-audit-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-audit-conf-datatypes.xsd"/>
 <xs:include schemaLocation="msml-audit-conn-datatypes.xsd"/>
 <xs:include schemaLocation="msml-audit-dialog-datatypes.xsd"/>
 <xs:include schemaLocation="msml-audit-stream-datatypes.xsd"/>
 <xs:element name="msml">
  <xs:complexType>
   <xs:choice>
    <xs:group ref="msmlRequestType" maxOccurs="unbounded"/>
    <xs:element name="event">
     <xs:complexType>
      <xs:choice maxOccurs="unbounded">
       <xs:sequence>
        <xs:element name="name" type="msmlEventNameValue.datatype"/>
        <xs:element name="value">
         <xs:simpleType>
          <xs:restriction base="xs:string">
           <xs:pattern value="[a-zA-Z0-9.]+"/>
          </xs:restriction>
         </xs:simpleType>
        </xs:element>
       </xs:sequence>
      </xs:choice>
      <xs:attribute name="name" type="msmlEventName.datatype"
                    use="required"/>
      <xs:attribute name="id" type="msmlEventSource.datatype"
                    use="required"/>
     </xs:complexType>
    </xs:element>
    <xs:element name="result">
     <xs:complexType>
      <xs:choice>
       <xs:element ref="description" minOccurs="0"/>
       <xs:sequence>
        <xs:element ref="msmlResultSimple" minOccurs="0"
                    maxOccurs="unbounded"/>
        <xs:element ref="msmlResultComplex" minOccurs="0"
                    maxOccurs="unbounded"/>
       </xs:sequence>
      </xs:choice>
      <xs:attribute name="response">
       <xs:simpleType>
        <xs:restriction base="xs:string">
         <xs:pattern value="\d{3}"/>
        </xs:restriction>
       </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="mark" type="mark.datatype"/>
     </xs:complexType>

    </xs:element>
   </xs:choice>
   <xs:attribute name="version" type="xs:string" use="required"
                 fixed="1.1"/>
  </xs:complexType>
 </xs:element>
</xs:schema>

16.1. MSML Core ๐Ÿงฉ

16.1.1. msml-core.xsd ๐Ÿ’…

ok this one is the core package's own schema, and it's giving a lot of dรฉjร  vu because it's basically the same as the full one above, just only pulling in msml-core-datatypes.xsd ๐Ÿซถ

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core-datatypes.xsd"/>
 <xs:element name="msml">
  <xs:complexType>
   <xs:choice>
    <xs:group ref="msmlRequestType" maxOccurs="unbounded"/>
    <xs:element name="event">
     <xs:complexType>
      <xs:choice maxOccurs="unbounded">
       <xs:sequence>
        <xs:element name="name" type="msmlEventNameValue.datatype"/>
        <xs:element name="value">
         <xs:simpleType>
          <xs:restriction base="xs:string">
           <xs:pattern value="[a-zA-Z0-9.]+"/>
          </xs:restriction>
         </xs:simpleType>
        </xs:element>
       </xs:sequence>
      </xs:choice>
      <xs:attribute name="name" type="msmlEventName.datatype"
                    use="required"/>
      <xs:attribute name="id" type="msmlEventSource.datatype"
                    use="required"/>
     </xs:complexType>
    </xs:element>
    <xs:element name="result">
     <xs:complexType>
      <xs:choice>
       <xs:element ref="description" minOccurs="0"/>
       <xs:sequence>
        <xs:element ref="msmlResultSimple" minOccurs="0"
                    maxOccurs="unbounded"/>
        <xs:element ref="msmlResultComplex" minOccurs="0"

                    maxOccurs="unbounded"/>
       </xs:sequence>
      </xs:choice>
      <xs:attribute name="response">
       <xs:simpleType>
        <xs:restriction base="xs:string">
         <xs:pattern value="\d{3}"/>
        </xs:restriction>
       </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="mark" type="mark.datatype"/>
     </xs:complexType>
    </xs:element>
   </xs:choice>
   <xs:attribute name="version" type="xs:string" use="required"
                 fixed="1.1"/>
  </xs:complexType>
 </xs:element>
</xs:schema>

16.1.2. msml-core-datatypes.xsd โœจ

Okay bestie, this is the datatypes file for the core schema ๐Ÿ’… Every value here is copied exactly from the original.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:group name="msmlRequestType">
  <xs:choice>
   <xs:element ref="msmlRequest"/>
   <xs:element name="send">
    <xs:complexType>
     <xs:complexContent>
      <xs:extension base="msmlRequestType">
       <xs:attribute name="event" type="msmlEvent.datatype"
                     use="required"/>
       <xs:attribute name="target" type="msmlTarget.datatype"
                    use="required"/>
       <xs:attribute name="valuelist" type="xs:string"/>
      </xs:extension>
     </xs:complexContent>
    </xs:complexType>
   </xs:element>
  </xs:choice>
 </xs:group>
 <xs:element name="msmlRequest" type="msmlRequestType"
             abstract="true"/>
 <xs:complexType name="msmlRequestType">
  <xs:attribute ref="mark"/>

 </xs:complexType>
 <xs:element name="msmlResultSimple" type="msmlResultSimpleType"
             abstract="true"/>
 <xs:element name="msmlResultComplex" type="msmlResultComplexType"
             abstract="true"/>
 <xs:simpleType name="msmlResultSimpleType">
  <xs:restriction base="xs:string"/>
 </xs:simpleType>
 <xs:complexType name="msmlResultComplexType"/>
 <xs:element name="description" type="xs:string"/>
 <xs:attribute name="mark" type="mark.datatype"/>
 <xs:simpleType name="msmlInstanceID.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="[a-zA-Z0-9.:\-_]+"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="connID.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="conn:[a-zA-Z0-9.:\-_]+"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="confID.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="conf:[a-zA-Z0-9.:\-_]+"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="dialogID.datatype">
  <xs:restriction base="xs:string">
<xs:pattern value="conf:[a-zA-Z0-9.:\-_]+/dialog:[a-zA-Z0-9.:\-_]+"/>
<xs:pattern value="conn:[a-zA-Z0-9.:\-_]+/dialog:[a-zA-Z0-9.:\-_]+"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="independentID.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="conf:[a-zA-Z0-9.:\-_]+"/>
   <xs:pattern value="conn:[a-zA-Z0-9.:\-_]+"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="dialogLanguage.datatype">
  <xs:restriction base="xs:string">
   <xs:enumeration value="application/moml+xml"/>
   <xs:enumeration value="application/voicexml+xml"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="msmlEvent.datatype">
  <xs:restriction base="xs:string"/>
 </xs:simpleType>
 <xs:simpleType name="msmlSend.datatype">

  <xs:restriction base="xs:string"/>
 </xs:simpleType>
 <xs:simpleType name="msmlEventName.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="msml.dialog.exit"/>
   <xs:pattern value="msml.conf.asn"/>
   <xs:pattern value="msml.conf.nomedia"/>
   <xs:pattern value="msml.dialog.exit"/>
   <xs:pattern value="[a-zA-Z0-9.:_\-]+"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="msmlTarget.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern
value="conf:[a-zA-Z0-9.:_\-]+(/oper:[a-zA-Z0-9.:_\-]+|\*)*"/>
   <xs:pattern
value="conn:[a-zA-Z0-9.:_\-]+(/oper:[a-zA-Z0-9.:_\-]+|\*)+"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="msmlEventSource.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="conf:[a-zA-Z0-9.:_\-]+"/>
   <xs:pattern value="(conf:[a-zA-Z0-9.:_\-]+|conn:[a-zA-Z0-9.:_\-
   ]+)/dialog:[a-zA-Z0-9.:_\-]+"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="msmlEventNameValue.datatype">
  <xs:restriction base="xs:string"/>
 </xs:simpleType>
 <xs:simpleType name="mark.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="[a-zA-Z0-9.:\-_]+"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="boolean.datatype">
  <xs:restriction base="xs:string">
   <xs:enumeration value="true"/>
   <xs:enumeration value="false"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="posDuration.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="(\+)?([0-9]*\.)?[0-9]+(ms|s)"/>
  </xs:restriction>
 </xs:simpleType>
</xs:schema>

16.2. MSML Conference Core Package ๐ŸŽ€

16.2.1. msml-conf-core.xsd ๐Ÿ’–

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
   <xs:include schemaLocation="msml-core.xsd"/>
   <xs:include schemaLocation="msml-conf-core-datatypes.xsd"/>
</xs:schema>

16.2.2. msml-conf-core-datatypes.xsd ๐Ÿฆ‹

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core-datatypes.xsd"/>
 <xs:element name="createconference" substitutionGroup="msmlRequest">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="msmlRequestType">
     <xs:all>
      <xs:element name="audiomix" type="audioMixType" minOccurs="0"/>
      <xs:element name="videolayout" type="videoLayoutType"
                  minOccurs="0"/>
      <xs:element name="reserve" minOccurs="0">
       <xs:complexType>
        <xs:sequence>
         <xs:element name="resource" maxOccurs="unbounded">
          <xs:complexType>
           <xs:sequence>
            <xs:any namespace="##other" processContents="lax"
                    minOccurs="0" maxOccurs="unbounded"/>
           </xs:sequence>
           <xs:attribute name="n" type="xs:positiveInteger"
                        default="1"/>
           <xs:anyAttribute namespace="##any"/>
          </xs:complexType>
         </xs:element>
        </xs:sequence>
        <xs:attribute name="required" type="boolean.datatype"
                      default="true"/>
       </xs:complexType>
      </xs:element>
     </xs:all>
     <xs:attribute name="name" type="msmlInstanceID.datatype"/>
     <xs:attribute name="deletewhen" default="never">
      <xs:simpleType>
       <xs:restriction base="xs:string">
        <xs:enumeration value="nomedia"/>
        <xs:enumeration value="nocontrol"/>
        <xs:enumeration value="never"/>
       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="term" type="boolean.datatype" default="true"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="modifyconference" substitutionGroup="msmlRequest">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="msmlRequestType">
     <xs:all>
      <xs:element name="audiomix" type="audioMixType" minOccurs="0"/>
      <xs:element name="videolayout" type="videoLayoutType"
                  minOccurs="0"/>
     </xs:all>
     <xs:attribute name="id" type="confID.datatype" use="required"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="destroyconference" substitutionGroup="msmlRequest">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="msmlRequestType">
     <xs:all>
      <xs:element name="audiomix" type="basicAudioMixType"
                  minOccurs="0"/>
      <xs:element name="videolayout" type="basicVideoLayoutType"
                  minOccurs="0"/>
     </xs:all>
     <xs:attribute name="id" type="confID.datatype" use="required"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="join" substitutionGroup="msmlRequest">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="msmlRequestType">
     <xs:sequence>

      <xs:element name="stream" type="streamType" minOccurs="0"
                  maxOccurs="4"/>
     </xs:sequence>
     <xs:attribute name="id1" type="independentID.datatype"
                   use="required"/>
     <xs:attribute name="id2" type="independentID.datatype"
                   use="required"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="modifystream" substitutionGroup="msmlRequest">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="msmlRequestType">
     <xs:sequence>
      <xs:element name="stream" type="streamType" maxOccurs="4"/>
     </xs:sequence>
     <xs:attribute name="id1" type="independentID.datatype"
                   use="required"/>
     <xs:attribute name="id2" type="independentID.datatype"
                   use="required"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="unjoin" substitutionGroup="msmlRequest">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="msmlRequestType">
     <xs:sequence>
      <xs:element name="stream" type="basicStreamType" minOccurs="0"
                  maxOccurs="4"/>
     </xs:sequence>
     <xs:attribute name="id1" type="independentID.datatype"
                   use="required"/>
     <xs:attribute name="id2" type="independentID.datatype"
                   use="required"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="monitor" substitutionGroup="msmlRequest">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="msmlRequestType">
     <xs:attribute name="id1" type="connID.datatype" use="required"/>
     <xs:attribute name="id2" type="independentID.datatype"

                   use="required"/>
     <xs:attribute name="compressed" type="boolean.datatype"
                   default="false"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="confid" type="msmlResultSimpleType"
             substitutionGroup="msmlResultSimple"/>
 <xs:complexType name="basicStreamType">
  <xs:attribute name="dir">
   <xs:simpleType>
    <xs:restriction base="xs:string">
     <xs:enumeration value="to-id1"/>
     <xs:enumeration value="from-id1"/>
    </xs:restriction>
   </xs:simpleType>
  </xs:attribute>
  <xs:attribute name="media">
   <xs:simpleType>
    <xs:restriction base="xs:string">
     <xs:enumeration value="audio"/>
     <xs:enumeration value="video"/>
    </xs:restriction>
   </xs:simpleType>
  </xs:attribute>
  <xs:attribute name="compressed" type="boolean.datatype"/>
 </xs:complexType>
 <xs:complexType name="streamType">
  <xs:complexContent>
   <xs:extension base="basicStreamType">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
     <xs:element name="gain">
      <xs:complexType>
       <xs:attribute name="amt" use="optional">
        <xs:simpleType>
         <xs:restriction base="xs:integer">
          <xs:minInclusive value="-96"/>
          <xs:maxInclusive value="96"/>
         </xs:restriction>
        </xs:simpleType>
       </xs:attribute>
       <xs:attribute name="agc" type="boolean.datatype"/>
       <xs:attribute name="tgtlvl" use="optional">
        <xs:simpleType>
         <xs:restriction base="xs:nonPositiveInteger">
          <xs:minInclusive value="-40"/>
          <xs:maxInclusive value="0"/>
         </xs:restriction>
        </xs:simpleType>
       </xs:attribute>
       <xs:attribute name="maxgain" default="10">
        <xs:simpleType>
         <xs:restriction base="xs:nonNegativeInteger">
          <xs:minInclusive value="0"/>
          <xs:maxInclusive value="40"/>
         </xs:restriction>
        </xs:simpleType>
       </xs:attribute>
      </xs:complexType>
     </xs:element>
     <xs:element name="clamp">
      <xs:complexType>
       <xs:attribute name="dtmf" type="boolean.datatype"/>
       <xs:attribute name="tones" type="boolean.datatype"/>
      </xs:complexType>
     </xs:element>
     <xs:element name="visual"/>
    </xs:choice>
    <xs:attribute name="preferred" type="boolean.datatype"
                  default="false"/>
    <xs:attribute name="display" type="xs:string"/>
    <xs:attribute name="override" type="boolean.datatype"
                  default="false"/>
   </xs:extension>
  </xs:complexContent>
 </xs:complexType>
 <xs:complexType name="basicAudioMixType">
  <xs:attribute name="id" type="xs:string" use="optional"/>
  <xs:attribute name="samplerate" type="xs:positiveInteger"
                use="optional" default="8000"/>
 </xs:complexType>
 <xs:complexType name="audioMixType">
  <xs:complexContent>
   <xs:extension base="basicAudioMixType">
    <xs:all>
     <xs:element name="asn" minOccurs="0">
      <xs:complexType>
       <xs:attribute name="ri" type="posDuration.datatype"/>
       <xs:attribute name="asth" default="-96">
        <xs:simpleType>
         <xs:restriction base="xs:nonPositiveInteger">
          <xs:minInclusive value="-96"/>
          <xs:maxInclusive value="0"/>
         </xs:restriction>
        </xs:simpleType>

       </xs:attribute>
      </xs:complexType>
     </xs:element>
     <xs:element name="n-loudest" minOccurs="0">
      <xs:complexType>
       <xs:attribute name="n" type="xs:positiveInteger" use="required"/>
      </xs:complexType>
     </xs:element>
    </xs:all>
   </xs:extension>
  </xs:complexContent>
 </xs:complexType>
 <xs:complexType name="basicVideoLayoutType">
  <xs:attribute name="id" type="xs:string" use="required"/>
  <xs:attribute name="type" type="xs:string" use="required"
                fixed="text/msml-basic-layout"/>
 </xs:complexType>
 <xs:complexType name="videoLayoutType">
  <xs:complexContent>
   <xs:extension base="basicVideoLayoutType">
    <xs:choice>
     <xs:element name="selector">
      <xs:complexType>
       <xs:complexContent>
        <xs:extension base="selectorType">
         <xs:choice>
          <xs:element name="root" type="rootType" minOccurs="0"/>
          <xs:element name="region" minOccurs="0">
           <xs:complexType>
            <xs:attribute name="id" type="xs:string" use="required"/>
            <xs:attribute name="left" type="xs:positiveInteger"/>
            <xs:attribute name="top" type="xs:positiveInteger"/>
            <xs:attribute name="relativeSize">
             <xs:simpleType>
              <xs:restriction base="xs:string">
               <xs:enumeration value="1/4"/>
               <xs:enumeration value="1/3"/>
               <xs:enumeration value="2/3"/>
               <xs:enumeration value="3/4"/>
               <xs:enumeration value="1"/>
              </xs:restriction>
             </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="priority">
             <xs:simpleType>
              <xs:restriction base="xs:float">
               <xs:minInclusive value="0"/>
               <xs:maxExclusive value="1"/>

              </xs:restriction>
             </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="title" type="xs:string"/>
            <xs:attribute name="titleTextColor" type="xs:string"/>
            <xs:attribute name="titleBackgroundColor" type="xs:string"/>
            <xs:attribute name="borderColor" type="xs:string"/>
            <xs:attribute name="borderWidth" type="xs:positiveInteger"/>
            <xs:attribute name="logo" type="xs:anyURI"/>
           </xs:complexType>
          </xs:element>
         </xs:choice>
        </xs:extension>
       </xs:complexContent>
      </xs:complexType>
     </xs:element>
     <xs:element name="root" type="rootType"/>
     <xs:element name="region" minOccurs="0" maxOccurs="unbounded">
      <xs:complexType>
       <xs:complexContent>
        <xs:extension base="regionType"/>
       </xs:complexContent>
      </xs:complexType>
     </xs:element>
    </xs:choice>
   </xs:extension>
  </xs:complexContent>
 </xs:complexType>
 <xs:complexType name="regionType">
  <xs:attribute name="id" type="xs:string" use="required"/>
  <xs:attribute name="left" type="xs:positiveInteger"/>
  <xs:attribute name="top" type="xs:positiveInteger"/>
  <xs:attribute name="relativeSize">
   <xs:simpleType>
    <xs:restriction base="xs:string">
     <xs:enumeration value="1/4"/>
     <xs:enumeration value="1/3"/>
     <xs:enumeration value="2/3"/>
     <xs:enumeration value="3/4"/>
     <xs:enumeration value="1"/>
    </xs:restriction>
   </xs:simpleType>
  </xs:attribute>
  <xs:attribute name="priority">
   <xs:simpleType>
    <xs:restriction base="xs:float">
     <xs:minInclusive value="0"/>
     <xs:maxExclusive value="1"/>

    </xs:restriction>
   </xs:simpleType>
  </xs:attribute>
  <xs:attribute name="title" type="xs:string"/>
  <xs:attribute name="titleTextColor" type="xs:string"/>
  <xs:attribute name="titleBackgroundColor" type="xs:string"/>
  <xs:attribute name="borderColor" type="xs:string"/>
  <xs:attribute name="borderWidth" type="xs:positiveInteger"/>
  <xs:attribute name="logo" type="xs:anyURI"/>
 </xs:complexType>
 <xs:complexType name="selectorType">
  <xs:attribute name="id" type="xs:string" use="required"/>
  <xs:attribute name="method" use="required">
   <xs:simpleType>
    <xs:restriction base="xs:string">
     <xs:enumeration value="vas"/>
     <xs:enumeration value="sequence"/>
    </xs:restriction>
   </xs:simpleType>
  </xs:attribute>
  <xs:attribute name="status" default="active">
   <xs:simpleType>
    <xs:restriction base="xs:string">
     <xs:enumeration value="active"/>
     <xs:enumeration value="disabled"/>
    </xs:restriction>
   </xs:simpleType>
  </xs:attribute>
  <xs:attribute name="si" type="posDuration.datatype" default="1s"/>
  <xs:attribute name="blankothers" type="xs:boolean" default="false"/>
  <xs:attribute name="speakersees" default="current">
   <xs:simpleType>
    <xs:restriction base="xs:string">
     <xs:enumeration value="current"/>
     <xs:enumeration value="previous"/>
    </xs:restriction>
   </xs:simpleType>
  </xs:attribute>
 </xs:complexType>
 <xs:complexType name="rootType">
  <xs:attribute name="size" default="CIF">
   <xs:simpleType>
    <xs:restriction base="xs:string">
     <xs:enumeration value="16CIF"/>
     <xs:enumeration value="4CIF"/>
     <xs:enumeration value="CIF"/>
     <xs:enumeration value="QCIF"/>
    </xs:restriction>

   </xs:simpleType>
  </xs:attribute>
  <xs:attribute name="backgroundcolor" type="xs:string"
                default="black"/>
  <xs:attribute name="backgroundimage" type="xs:anyURI"/>
 </xs:complexType>
 <xs:simpleType name="confclass.datatype">
  <xs:restriction base="xs:string">
   <xs:enumeration value="standard"/>
   <xs:enumeration value="preferred"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="conferenceType.datatype">
  <xs:restriction base="xs:string">
   <xs:enumeration value="audio.basic"/>
   <xs:enumeration value="audio.advanced"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="duplex.datatype">
  <xs:restriction base="xs:string">
   <xs:enumeration value="half"/>
   <xs:enumeration value="full"/>
  </xs:restriction>
 </xs:simpleType>
</xs:schema>

16.3. MSML Dialog Packages โœจ

okay the schema is giving ๐Ÿ’… and now we get the dialog packages, which are basically their own little family of schemas ๐ŸŽ€ they pull in the core stuff with xs:include, so the core bits just come along for the ride ๐Ÿฆ‹

16.3.1. msml-dialog-core.xsd ๐Ÿ’–

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core.xsd"/>
 <xs:include schemaLocation="msml-dialog-core-datatypes.xsd"/>
</xs:schema>

16.3.2. msml-dialog-core-datatypes.xsd ๐ŸŽ€

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

bestie, that's where this part stops ๐Ÿซถ

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core-datatypes.xsd"/>
 <xs:group name="momlRequest">
  <xs:choice>
   <xs:group ref="executeType"/>
   <xs:group ref="sendType"/>
  </xs:choice>
 </xs:group>
 <xs:element name="dialogstart" substitutionGroup="msmlRequest">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="msmlRequestType">
     <xs:choice>
      <xs:group ref="momlRequest" minOccurs="0"/>
     </xs:choice>
     <xs:attribute name="target" type="independentID.datatype"
                   use="required"/>
     <xs:attribute name="type" type="dialogLanguage.datatype"
                   use="required"/>
     <xs:attribute name="name" type="msmlInstanceID.datatype"/>
     <xs:attribute name="src" type="xs:anyURI" use="optional"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="dialogend" substitutionGroup="msmlRequest">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="msmlRequestType">
     <xs:attribute name="id" type="dialogID.datatype" use="required"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="dialogid" type="msmlResultSimpleType"
             substitutionGroup="msmlResultSimple"/>
 <xs:group name="executeType">
  <xs:choice>
   <xs:element ref="primitive" maxOccurs="unbounded"/>
   <xs:element ref="control" maxOccurs="unbounded"/>
  </xs:choice>
 </xs:group>
 <xs:element name="primitive" type="primitiveType" abstract="true"/>
 <xs:complexType name="primitiveType">
  <xs:attribute name="id" type="momlID.datatype"/>
 </xs:complexType>
 <xs:element name="control" abstract="true"/>
 <xs:group name="sendType">
  <xs:choice>
   <xs:choice>
    <xs:element name="exit" type="exitType"/>
    <xs:element name="disconnect" type="exitType"/>
   </xs:choice>
   <xs:sequence>
    <xs:element ref="send" maxOccurs="unbounded"/>
    <xs:choice minOccurs="0">
     <xs:element name="exit" type="exitType"/>
     <xs:element name="disconnect" type="exitType"/>
    </xs:choice>
   </xs:sequence>
  </xs:choice>
 </xs:group>
 <xs:element name="send">
  <xs:complexType>
   <xs:attribute name="event" type="momlEvent.datatype" use="required"/>
   <xs:attribute name="target" type="momlTarget.datatype"
                 use="required"/>
   <xs:attribute name="namelist" type="momlNamelist.datatype"/>
  </xs:complexType>
 </xs:element>
 <xs:complexType name="exitType">
  <xs:attribute name="namelist" type="momlNamelist.datatype"/>
 </xs:complexType>
 <xs:simpleType name="momlID.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="[a-zA-Z0-9][a-zA-Z0-9._\-]*"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="momlEvent.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="[a-zA-Z0-9][a-zA-Z0-9._\-]*"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="momlNamelist.datatype">
  <xs:restriction base="xs:string"/>
 </xs:simpleType>
 <xs:simpleType name="dtmfDigits.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="[0-9#*]+"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="iterate.datatype">
  <xs:union memberTypes="xs:positiveInteger">
   <xs:simpleType>
    <xs:restriction base="xs:negativeInteger">
     <xs:minInclusive value="-1"/>
    </xs:restriction>
   </xs:simpleType>
   <xs:simpleType>
    <xs:restriction base="xs:string">
     <xs:enumeration value="forever"/>

    </xs:restriction>
   </xs:simpleType>
  </xs:union>
 </xs:simpleType>
 <xs:simpleType name="momlTarget.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="[a-zA-Z0-9][a-zA-Z0-9._\-]*"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="duration.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="(\+|\-)?([0-9]*\.)?[0-9]+(ms|s)"/>
  </xs:restriction>
 </xs:simpleType>
</xs:schema>

16.3.3. msml-dialog-base.xsd โœจ

Okay, next up is the base schema, and it's basically a little bundle of includes, bestie ๐Ÿงš Here it is:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="unqualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core.xsd"/>
 <xs:include schemaLocation="msml-dialog-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-base-datatypes.xsd"/>
</xs:schema>

16.3.4. msml-dialog-base-datatypes.xsd ๐Ÿ’œ

Now the base datatypes, and this one is giving main character energy ๐Ÿ’… It has the play and record elements, so let's look:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="unqualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-dialog-core-datatypes.xsd"/>
 <xs:import namespace="http://www.w3.org/XML/1998/namespace"
            schemaLocation="http://www.w3.org/2001/xml.xsd"/>
 <xs:element name="play" substitutionGroup="primitive">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="primitiveType">
     <xs:sequence>
      <xs:choice maxOccurs="unbounded">
       <xs:element name="audio" minOccurs="0" maxOccurs="unbounded">
        <xs:complexType>
         <xs:attribute name="uri" type="xs:anyURI" use="required"/>
         <xs:attribute name="iterate" type="iterate.datatype"
                       default="1"/>
         <xs:attribute name="format" type="xs:string" use="optional"/>
         <xs:attribute name="audiosamplerate" type="xs:positiveInteger"
                       use="optional"/>
         <xs:attribute name="audiosamplesize" type="xs:positiveInteger"
                       use="optional"/>
         <xs:attribute ref="xml:lang"/>
        </xs:complexType>
       </xs:element>
       <xs:element name="video" minOccurs="0" maxOccurs="unbounded">
        <xs:complexType>
         <xs:attribute name="uri" type="xs:anyURI" use="required"/>
         <xs:attribute name="iterate" type="iterate.datatype"
                       use="optional" default="1"/>
         <xs:attribute name="format" type="xs:string" use="optional"/>
         <xs:attribute name="audiosamplerate" type="xs:positiveInteger"
                       use="optional"/>
         <xs:attribute name="audiosamplesize" type="xs:positiveInteger"
                       use="optional"/>
         <xs:attribute name="codecconfig" type="xs:string"
                       use="optional"/>
         <xs:attribute name="profile" type="xs:string" use="optional"/>
         <xs:attribute name="level" type="xs:string" use="optional"/>
         <xs:attribute name="imagewidth" type="xs:positiveInteger"
                       use="optional"/>
         <xs:attribute name="imageheight" type="xs:positiveInteger"
                       use="optional"/>
         <xs:attribute name="maxbitrate" type="xs:positiveInteger"
                       use="optional"/>
         <xs:attribute name="framerate" type="xs:positiveInteger"
                       use="optional"/>
        </xs:complexType>
       </xs:element>
       <xs:element name="media" minOccurs="0" maxOccurs="unbounded">
        <xs:complexType>
         <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="audio" minOccurs="0">
           <xs:complexType>
            <xs:attribute name="uri" type="xs:anyURI" use="required"/>
            <xs:attribute name="iterate" type="iterate.datatype"
                          default="1"/>
            <xs:attribute name="format" type="xs:string"
                          use="optional"/>
            <xs:attribute name="audiosamplerate"
                          type="xs:positiveInteger" use="optional"/>
            <xs:attribute name="audiosamplesize"
                          type="xs:positiveInteger" use="optional"/>
            <xs:attribute ref="xml:lang"/>
           </xs:complexType>
          </xs:element>
          <xs:element name="video" minOccurs="0">
           <xs:complexType>
            <xs:attribute name="uri" type="xs:anyURI" use="required"/>
            <xs:attribute name="iterate" type="iterate.datatype"
                          use="optional" default="1"/>
            <xs:attribute name="format" type="xs:string"
                          use="optional"/>
            <xs:attribute name="audiosamplerate"
                          type="xs:positiveInteger" use="optional"/>
            <xs:attribute name="audiosamplesize"
                          type="xs:positiveInteger" use="optional"/>
            <xs:attribute name="codecconfig" type="xs:string"
                          use="optional"/>
            <xs:attribute name="profile" type="xs:string"
                          use="optional"/>
            <xs:attribute name="level" type="xs:string" use="optional"/>
            <xs:attribute name="imagewidth" type="xs:positiveInteger"
                          use="optional"/>
            <xs:attribute name="imageheight" type="xs:positiveInteger"
                          use="optional"/>
            <xs:attribute name="maxbitrate" type="xs:positiveInteger"
                          use="optional"/>
            <xs:attribute name="framerate" type="xs:positiveInteger"
                          use="optional"/>
           </xs:complexType>
          </xs:element>
         </xs:choice>
        </xs:complexType>
       </xs:element>
       <xs:element ref="smedia" minOccurs="0" maxOccurs="unbounded"/>
      </xs:choice>
      <xs:choice minOccurs="0">
       <xs:element name="playexit">
        <xs:complexType>
         <xs:group ref="sendType"/>
        </xs:complexType>
       </xs:element>
      </xs:choice>
     </xs:sequence>
     <xs:attribute name="interval" type="posDuration.datatype"
                   use="optional"/>
     <xs:attribute name="iterate" type="iterate.datatype" use="optional"
                   default="1"/>
     <xs:attribute name="offset" type="duration.datatype"
                   use="optional"/>
     <xs:attribute name="initial" use="optional" default="generate">
      <xs:simpleType>
       <xs:restriction base="xs:string">

        <xs:enumeration value="generate"/>
        <xs:enumeration value="suspend"/>
       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="maxtime" type="posDuration.datatype"
                   use="optional"/>
     <xs:attribute name="skip" type="duration.datatype" use="optional"
                   default="3s"/>
     <xs:attribute name="barge" type="boolean.datatype" use="optional"
                   default="false"/>
     <xs:attribute name="cleardb" type="boolean.datatype" use="optional"
                   default="false"/>
     <xs:attribute ref="xml:lang"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="record" substitutionGroup="primitive">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="primitiveType">
     <xs:choice minOccurs="0">
      <xs:element ref="play" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element ref="tonegen" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element name="recordexit">
       <xs:complexType>
        <xs:group ref="sendType"/>
       </xs:complexType>
      </xs:element>
     </xs:choice>
     <xs:attribute name="append" type="boolean.datatype" use="optional"
                   default="false"/>
     <xs:attribute name="dest" type="xs:anyURI" use="optional"/>
     <xs:attribute name="audiodest" type="xs:anyURI" use="optional"/>
     <xs:attribute name="videodest" type="xs:anyURI" use="optional"/>
     <xs:attribute name="format" use="required">
      <xs:simpleType>
       <xs:restriction base="xs:string"/>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="codecconfig" use="optional">
      <xs:simpleType>
       <xs:restriction base="xs:string"/>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="audiosamplerate" type="xs:positiveInteger"
                   use="optional"/>
     <xs:attribute name="audiosamplesize" type="xs:positiveInteger"
                   use="optional"/>
     <xs:attribute name="profile" use="optional">
      <xs:simpleType>
       <xs:restriction base="xs:string"/>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="level" use="optional">
      <xs:simpleType>
       <xs:restriction base="xs:string"/>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="imagewidth" type="xs:positiveInteger"
                   use="optional"/>
     <xs:attribute name="imageheight" type="xs:positiveInteger"
                   use="optional"/>
     <xs:attribute name="maxbitrate" type="xs:positiveInteger"
                   use="optional"/>
     <xs:attribute name="framerate" type="xs:positiveInteger"
                   use="optional"/>
     <xs:attribute name="maxtime" type="posDuration.datatype"
                   use="required"/>
     <xs:attribute name="initial" use="optional" default="create">
      <xs:simpleType>
       <xs:restriction base="xs:string">
        <xs:enumeration value="create"/>
        <xs:enumeration value="suspend"/>
       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="prespeech" type="posDuration.datatype"
                   use="optional" default="0s"/>
     <xs:attribute name="postspeech" type="posDuration.datatype"
                   use="optional" default="0s"/>
     <xs:attribute name="termkey" use="optional">
      <xs:simpleType>
       <xs:restriction base="xs:string">
        <xs:pattern value="[0-9#*ABCD]"/>
       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="dtmf" substitutionGroup="primitive">
  <xs:complexType>
   <xs:complexContent>

    <xs:extension base="primitiveType">
     <xs:sequence>
      <xs:element name="pattern" maxOccurs="unbounded">
       <xs:complexType>
        <xs:group ref="sendType"/>
        <xs:attribute name="digits" type="xs:string" use="required"/>
        <xs:attribute name="format">
         <xs:simpleType>
          <xs:restriction base="xs:string">
           <xs:enumeration value="mgcp"/>
           <xs:enumeration value="megaco"/>
           <xs:enumeration value="moml+digits"/>
          </xs:restriction>
         </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="iterate" type="iterate.datatype"
                      default="1"/>
       </xs:complexType>
      </xs:element>
      <xs:element name="detect" minOccurs="0">
       <xs:complexType>
        <xs:group ref="sendType"/>
       </xs:complexType>
      </xs:element>
      <xs:element name="noinput" type="iterateSendType" minOccurs="0"/>
      <xs:element name="nomatch" type="iterateSendType" minOccurs="0"/>
      <xs:element name="dtmfexit" minOccurs="0">
       <xs:complexType>
        <xs:group ref="sendType"/>
       </xs:complexType>
      </xs:element>
      <xs:element ref="play" minOccurs="0"/>
     </xs:sequence>
     <xs:attribute name="cleardb" type="boolean.datatype"
                   default="true"/>
     <xs:attribute name="fdt" type="posDuration.datatype" default="0s"/>
     <xs:attribute name="idt" type="posDuration.datatype" default="4s"/>
     <xs:attribute name="edt" type="posDuration.datatype" default="4s"/>
     <xs:attribute name="starttimer" type="boolean.datatype"
                   default="false"/>
     <xs:attribute name="iterate" type="iterate.datatype" default="1"/>
     <xs:attribute name="ldd" type="posDuration.datatype" default="0s"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="collect" substitutionGroup="primitive">
  <xs:complexType>

   <xs:complexContent>
    <xs:extension base="primitiveType">
     <xs:sequence>
      <xs:element name="pattern" maxOccurs="unbounded">
       <xs:complexType>
        <xs:group ref="sendType"/>
        <xs:attribute name="digits" type="xs:string" use="required"/>
        <xs:attribute name="format">
         <xs:simpleType>
          <xs:restriction base="xs:string">
           <xs:enumeration value="mgcp"/>
           <xs:enumeration value="megaco"/>
           <xs:enumeration value="moml+digits"/>
          </xs:restriction>
         </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="iterate" type="iterate.datatype"
                      default="1"/>
       </xs:complexType>
      </xs:element>
      <xs:element name="detect" minOccurs="0">
       <xs:complexType>
        <xs:group ref="sendType"/>
       </xs:complexType>
      </xs:element>
      <xs:element name="noinput" type="iterateSendType" minOccurs="0"/>
      <xs:element name="nomatch" type="iterateSendType" minOccurs="0"/>
      <xs:element name="dtmfexit" minOccurs="0">
       <xs:complexType>
        <xs:group ref="sendType"/>
       </xs:complexType>
      </xs:element>
      <xs:element ref="play" minOccurs="0"/>
     </xs:sequence>
     <xs:attribute name="cleardb" type="boolean.datatype"
                   default="true"/>
     <xs:attribute name="fdt" type="posDuration.datatype" default="0s"/>
     <xs:attribute name="idt" type="posDuration.datatype" default="4s"/>
     <xs:attribute name="edt" type="posDuration.datatype" default="4s"/>
     <xs:attribute name="starttimer" type="boolean.datatype"
                   default="false"/>
     <xs:attribute name="iterate" type="iterate.datatype" default="1"/>
     <xs:attribute name="ldd" type="posDuration.datatype"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="dtmfgen" substitutionGroup="primitive">

  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="primitiveType">
     <xs:choice minOccurs="0">
      <xs:element name="dtmfgenexit">
       <xs:complexType>
        <xs:group ref="sendType"/>
       </xs:complexType>
      </xs:element>
     </xs:choice>
     <xs:attribute name="level" use="optional" default="-6">
      <xs:simpleType>
       <xs:restriction base="xs:nonPositiveInteger">
        <xs:maxInclusive value="0"/>
        <xs:minInclusive value="-96"/>
       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="digits" type="dtmfDigits.datatype"
                   use="required"/>
     <xs:attribute name="dur" type="posDuration.datatype" use="optional"
                   default="100ms"/>
     <xs:attribute name="interval" type="posDuration.datatype"
                   use="optional" default="100ms"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="tonegen" substitutionGroup="primitive">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="primitiveType">
     <xs:choice minOccurs="0">
      <xs:element name="tonegenexit" minOccurs="0">
       <xs:complexType>
        <xs:group ref="sendType"/>
       </xs:complexType>
      </xs:element>
      <xs:element name="tone" maxOccurs="unbounded">
       <xs:complexType>
        <xs:sequence>
         <xs:element name="tone1">
          <xs:complexType>
           <xs:attribute name="freq" use="required">
            <xs:simpleType>
             <xs:restriction base="xs:unsignedInt">
              <xs:minInclusive value="0"/>
              <xs:maxInclusive value="3999"/>

             </xs:restriction>
            </xs:simpleType>
           </xs:attribute>
           <xs:attribute name="atten" use="required">
            <xs:simpleType>
             <xs:restriction base="xs:nonPositiveInteger">
              <xs:minInclusive value="-96"/>
              <xs:maxInclusive value="0"/>
             </xs:restriction>
            </xs:simpleType>
           </xs:attribute>
          </xs:complexType>
         </xs:element>
         <xs:element name="tone2">
          <xs:complexType>
           <xs:attribute name="freq" use="required">
            <xs:simpleType>
             <xs:restriction base="xs:unsignedInt">
              <xs:minInclusive value="0"/>
              <xs:maxInclusive value="3999"/>
             </xs:restriction>
            </xs:simpleType>
           </xs:attribute>
           <xs:attribute name="atten" use="required">
            <xs:simpleType>
             <xs:restriction base="xs:nonPositiveInteger">
              <xs:minInclusive value="-96"/>
              <xs:maxInclusive value="0"/>
             </xs:restriction>
            </xs:simpleType>
           </xs:attribute>
          </xs:complexType>
         </xs:element>
         <xs:element name="silence" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
           <xs:attribute name="duration" type="duration.datatype"
                         use="required"/>
          </xs:complexType>
         </xs:element>
        </xs:sequence>
        <xs:attribute name="duration" use="required">
         <xs:simpleType>
          <xs:restriction base="duration.datatype"/>
         </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="iterate" type="iterate.datatype"
                      use="optional" default="1"/>
       </xs:complexType>

      </xs:element>
      <xs:element name="silence" minOccurs="0" maxOccurs="unbounded">
       <xs:complexType>
        <xs:attribute name="duration" type="duration.datatype"
                      use="required"/>
       </xs:complexType>
      </xs:element>
     </xs:choice>
     <xs:attribute name="iterate" type="iterate.datatype" use="optional"
                   default="1"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:complexType name="iterateSendType">
  <xs:group ref="sendType"/>
  <xs:attribute name="iterate" type="iterate.datatype" default="1"/>
 </xs:complexType>
 <xs:element name="smedia" type="smediaType" abstract="true"/>
 <xs:complexType name="smediaType">
  <xs:attribute ref="xml:lang"/>
  <xs:attribute name="iterate" type="iterate.datatype"/>
 </xs:complexType>
 <xs:element name="var" substitutionGroup="smedia">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="smediaType">
     <xs:attribute name="type" use="required">
      <xs:simpleType>
       <xs:restriction base="xs:string">
        <xs:enumeration value="date"/>
        <xs:enumeration value="digits"/>
        <xs:enumeration value="duration"/>
        <xs:enumeration value="month"/>
        <xs:enumeration value="money"/>
        <xs:enumeration value="number"/>
        <xs:enumeration value="silence"/>
        <xs:enumeration value="time"/>
        <xs:enumeration value="weekday"/>
       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="subtype" type="xs:string" use="optional"/>
     <xs:attribute name="value" type="xs:string" use="required"/>
    </xs:extension>
   </xs:complexContent>

  </xs:complexType>
 </xs:element>
</xs:schema>

16.3.5. msml-dialog-transform.xsd ๐ŸŽ€

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="unqualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core.xsd"/>
 <xs:include schemaLocation="msml-dialog-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-transform-datatypes.xsd"/>
</xs:schema>

16.3.6. msml-dialog-transform-datatypes.xsd ๐Ÿงš

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="unqualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-dialog-core-datatypes.xsd"/>
 <xs:import namespace="http://www.w3.org/XML/1998/namespace"
            schemaLocation="http://www.w3.org/2001/xml.xsd"/>
 <xs:element name="vad" substitutionGroup="primitive">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="primitiveType">
     <xs:all>
      <xs:element name="voice" type="vadPatternType" minOccurs="0"/>
      <xs:element name="silence" type="vadPatternType" minOccurs="0"/>
      <xs:element name="tvoice" type="vadPatternType" minOccurs="0"/>
      <xs:element name="tsilence" type="vadPatternType" minOccurs="0"/>
     </xs:all>
     <xs:attribute name="starttimer" type="boolean.datatype"
                   default="false"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="gain" substitutionGroup="primitive">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="primitiveType">
     <xs:attribute name="incr" default="3">
      <xs:simpleType>
       <xs:restriction base="xs:positiveInteger">
        <xs:maxInclusive value="96"/>

       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="amt" use="required">
      <xs:simpleType>
       <xs:restriction base="xs:integer">
        <xs:minInclusive value="-96"/>
        <xs:maxInclusive value="96"/>
       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="agc" substitutionGroup="primitive">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="primitiveType">
     <xs:attribute name="tgtlvl" use="required">
      <xs:simpleType>
       <xs:restriction base="xs:nonPositiveInteger">
        <xs:minInclusive value="-40"/>
        <xs:maxInclusive value="0"/>
       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="maxgain" default="10">
      <xs:simpleType>
       <xs:restriction base="xs:nonNegativeInteger">
        <xs:minInclusive value="0"/>
        <xs:maxInclusive value="40"/>
       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="gate" substitutionGroup="primitive">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="primitiveType">
     <xs:attribute name="initial" default="pass">
      <xs:simpleType>
       <xs:restriction base="xs:string">
        <xs:enumeration value="pass"/>
        <xs:enumeration value="halt"/>

       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="clamp" substitutionGroup="primitive">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="primitiveType"/>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="relay" substitutionGroup="primitive">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="primitiveType"/>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:complexType name="vadPatternType">
  <xs:group ref="sendType"/>
  <xs:attribute name="iterate" type="iterate.datatype" default="1"/>
  <xs:attribute name="len" type="posDuration.datatype" use="required"/>
  <xs:attribute name="sen" type="posDuration.datatype" use="optional"/>
 </xs:complexType>
</xs:schema>

16.3.7. msml-dialog-group.xsd โœจ

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="unqualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core.xsd"/>
 <xs:include schemaLocation="msml-dialog-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-base-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-group-datatypes.xsd"/>
</xs:schema>

16.3.8. msml-dialog-group-datatypes.xsd ๐Ÿ’…

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="unqualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-base-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-transform-datatypes.xsd"/>
 <xs:element name="group" substitutionGroup="control">
  <xs:complexType>
   <xs:sequence>
    <xs:group ref="executeType"/>
    <xs:element name="groupexit" minOccurs="0">
     <xs:complexType>
      <xs:group ref="sendType"/>
     </xs:complexType>
    </xs:element>
   </xs:sequence>
   <xs:attribute name="id" type="momlID.datatype"/>
   <xs:attribute name="topology" use="required">
    <xs:simpleType>
     <xs:restriction base="xs:string">
      <xs:enumeration value="serial"/>
      <xs:enumeration value="parallel"/>
      <xs:enumeration value="fullduplex"/>
     </xs:restriction>
    </xs:simpleType>
   </xs:attribute>
  </xs:complexType>
 </xs:element>
</xs:schema>

16.3.9. msml-dialog-speech.xsd ๐ŸŽ€

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core.xsd"/>
 <xs:include schemaLocation="msml-dialog-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-base-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-speech-datatypes.xsd"/>
</xs:schema>

16.3.10. msml-dialog-speech-datatypes.xsd ๐Ÿฆ‹

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-dialog-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-base-datatypes.xsd"/>
 <xs:include schemaLocation="http://www.w3.org/TR/2002/WD-speech-

             synthesis-20020405/synthesis-core.xsd"/>
 <xs:include schemaLocation="http://www.w3.org/TR/speech-
             grammar/grammar-core.xsd"/>
 <xs:element name="speech" substitutionGroup="primitive">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="primitiveType">
     <xs:sequence>
      <xs:element name="grammar" maxOccurs="unbounded">
       <xs:complexType>
        <xs:complexContent>
         <xs:extension base="grammar">
          <xs:choice>
           <xs:element name="match" type="iterateSendType"
                       minOccurs="0"/>
          </xs:choice>
          <xs:attribute name="uri" type="xs:anyURI"/>
          <xs:attribute name="iterate" type="iterate.datatype"
                        default="1"/>
         </xs:extension>
        </xs:complexContent>
       </xs:complexType>
      </xs:element>
      <xs:element name="noinput" type="iterateSendType" minOccurs="0"/>
      <xs:element name="nomatch" type="iterateSendType" minOccurs="0"/>
      <xs:element name="speechexit" minOccurs="0">
       <xs:complexType>
        <xs:group ref="sendType"/>
       </xs:complexType>
      </xs:element>
     </xs:sequence>
     <xs:attribute name="noint" type="posDuration.datatype"/>
     <xs:attribute name="norect" type="posDuration.datatype"/>
     <xs:attribute name="spcmplt" type="posDuration.datatype"/>
     <xs:attribute name="confidence">
      <xs:simpleType>
       <xs:restriction base="xs:positiveInteger">
        <xs:maxInclusive value="100"/>
       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="sens" type="xs:positiveInteger"/>
     <xs:attribute name="starttimer" type="boolean.datatype"
                   default="false"/>
     <xs:attribute name="iterate" type="iterate.datatype" default="1"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>

 </xs:element>
 <xs:element name="tts" type="smediaType" substitutionGroup="smedia"/>
</xs:schema>

16.3.11. msml-dialog-fax-detect.xsd ๐Ÿงš

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core.xsd"/>
 <xs:include schemaLocation="msml-dialog-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-fax-detect-datatypes.xsd"/>
</xs:schema>

16.3.12. msml-dialog-fax-detect-datatypes.xsd ๐ŸŒธ

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-dialog-core-datatypes.xsd"/>
 <xs:element name="faxdetect" substitutionGroup="primitive">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="primitiveType">
     <xs:choice minOccurs="0">
      <xs:element name="faxdetectexit">
       <xs:complexType>
        <xs:group ref="sendType"/>
       </xs:complexType>
      </xs:element>
     </xs:choice>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
</xs:schema>

16.3.13. msml-dialog-fax-sendrecv.xsd ๐Ÿ“

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core.xsd"/>
 <xs:include schemaLocation="msml-dialog-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-dialog-fax-sendrecv-datatypes.xsd"/>

</xs:schema>

16.3.14. msml-dialog-fax-sendrecv-datatypes.xsd ๐Ÿซถ

<?xml version="1.0" encoding="UTF-8"?>
 <xs:include schemaLocation="msml-dialog-core-datatypes.xsd"/>
 <xs:element name="faxsend" substitutionGroup="primitive">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="primitiveType">
     <xs:sequence>
      <xs:element name="sendobj" type="sendobjType" minOccurs="0"
          maxOccurs="unbounded"/>
      <xs:element name="hdrfooter" type="hdrfooterType" minOccurs="0"/>
      <xs:element name="rxpoll" minOccurs="0">
       <xs:complexType>
        <xs:sequence>
         <xs:element name="rcvobj" type="rcvobjType"
                     maxOccurs="unbounded"/>
         <xs:element name="hdrfooter" type="hdrfooterType"
                     minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="rmtid" type="faxid.datatype"
                      use="required"/>
       </xs:complexType>
      </xs:element>
      <xs:group ref="faxstatusrequest"/>
     </xs:sequence>
     <xs:attribute name="lclid" type="faxid.datatype" use="optional"/>
     <xs:attribute name="minspeed" type="faxspeed.datatype"
                   use="optional"/>
     <xs:attribute name="maxspeed" type="faxspeed.datatype"
                   use="optional"/>
     <xs:attribute name="ecm" type="boolean.datatype" use="optional"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="faxrecv" substitutionGroup="primitive">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="primitiveType">
     <xs:sequence>
      <xs:element name="rcvobj" type="rcvobjType" minOccurs="0"
                  maxOccurs="unbounded"/>

      <xs:element name="hdrfooter" type="hdrfooterType" minOccurs="0"/>
      <xs:element name="txpoll" minOccurs="0">
       <xs:complexType>
        <xs:sequence>
         <xs:element name="sendobj" type="sendobjType"
                     maxOccurs="unbounded"/>
         <xs:element name="hdrfooter" type="hdrfooterType"
                     minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="rmtid" type="faxid.datatype"/>
       </xs:complexType>
      </xs:element>
      <xs:group ref="faxstatusrequest"/>
     </xs:sequence>
     <xs:attribute name="lclid" type="faxid.datatype" use="optional"/>
     <xs:attribute name="ecm" type="boolean.datatype" default="true"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:group name="faxstatusrequest">
  <xs:sequence>
   <xs:element name="faxstart" minOccurs="0"/>
   <xs:element name="faxnegotiate" minOccurs="0"/>
   <xs:element name="faxpagedone" minOccurs="0"/>
   <xs:element name="faxobjectdone" minOccurs="0"/>
   <xs:element name="faxopcomplete" minOccurs="0"/>
   <xs:element name="faxpollstart" minOccurs="0"/>
  </xs:sequence>
 </xs:group>
 <xs:complexType name="hdrfooterType">
  <xs:choice>
   <xs:element name="format" type="xs:string" minOccurs="0"
               maxOccurs="unbounded"/>
  </xs:choice>
  <xs:attribute name="type" type="hdrfooter.datatype"/>
  <xs:attribute name="style" type="hdrfooterstyle.datatype"/>
 </xs:complexType>
 <xs:complexType name="formatType">
  <xs:simpleContent>
   <xs:extension base="xs:string">
    <xs:attribute name="style">
     <xs:simpleType>
      <xs:restriction base="xs:string">
       <xs:enumeration value="append"/>
       <xs:enumeration value="overlay"/>
       <xs:enumeration value="replace"/>
      </xs:restriction>

     </xs:simpleType>
    </xs:attribute>
   </xs:extension>
  </xs:simpleContent>
 </xs:complexType>
 <xs:complexType name="rcvobjType">
  <xs:attribute name="objuri" type="xs:anyURI" use="required"/>
  <xs:attribute name="maxpages" type="xs:positiveInteger"/>
 </xs:complexType>
 <xs:complexType name="sendobjType">
  <xs:attribute name="objuri" type="xs:anyURI" use="required"/>
  <xs:attribute name="startpage" type="xs:positiveInteger"/>
  <xs:attribute name="pagecount" type="xs:positiveInteger"/>
 </xs:complexType>
 <xs:simpleType name="faxid.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="[0-9+*- ]{20}"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="faxspeed.datatype">
  <xs:restriction base="xs:string">
   <xs:enumeration value="2400"/>
   <xs:enumeration value="4800"/>
   <xs:enumeration value="7200"/>
   <xs:enumeration value="9600"/>
   <xs:enumeration value="12000"/>
   <xs:enumeration value="14400"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="hdrfooter.datatype">
  <xs:restriction base="xs:string">
   <xs:enumeration value="header"/>
   <xs:enumeration value="footer"/>
   <xs:enumeration value="autohdr"/>
   <xs:enumeration value="nohdr"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="hdrfooterstyle.datatype">
  <xs:restriction base="xs:string">
   <xs:enumeration value="append"/>
   <xs:enumeration value="overlay"/>
   <xs:enumeration value="replace"/>
  </xs:restriction>
 </xs:simpleType>
</xs:schema>

16.4. MSML Audit Packages โœจ

okay, the audit packages are up next and they're giving main character energy ๐Ÿ’…๐Ÿฆ‹

16.4.1. msml-audit-core.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core.xsd"/>
 <xs:include schemaLocation="msml-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-audit-core-datatypes.xsd"/>
</xs:schema>

16.4.2. msml-audit-core-datatypes.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core-datatypes.xsd"/>
 <xs:element name="audit" substitutionGroup="msmlRequest">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="msmlRequestType">
     <xs:attribute name="queryid" type="auditQueryId.datatype"
                   use="required"/>
     <xs:attribute name="statelist" type="auditStateList.datatype"
                   use="optional"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="auditresult" substitutionGroup="msmlResultComplex">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="msmlResultComplexType">
    <xs:choice maxOccurs="unbounded">
     <xs:element ref="stateParameter"/>
     <xs:element ref="stateParameterSimple"/>
     </xs:choice>
     <xs:attribute name="targetid" type="independentID.datatype"
                   use="required"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="stateParameter" type="stateParameterType"
             abstract="true"/>

 <xs:element name="stateParameterSimple" type="stateParameterSimpleType"
             abstract="true"/>
 <xs:complexType name="stateParameterType"/>
 <xs:simpleType name="stateParameterSimpleType">
  <xs:restriction base="xs:string"/>
 </xs:simpleType>
 <xs:simpleType name="auditQueryId.datatype">
  <xs:restriction base="xs:string">
   <xs:pattern value="conf:[a-zA-Z0-9.:\-_]+"/>
   <xs:pattern value="conn:[a-zA-Z0-9.:\-_]+"/>
   <xs:pattern value="conf:\*"/>
   <xs:pattern value="conn:\*"/>
  </xs:restriction>
 </xs:simpleType>
 <xs:simpleType name="auditStateList.datatype">
  <xs:restriction base="xs:string"/>
 </xs:simpleType>
</xs:schema>

16.4.3. msml-audit-conf.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core.xsd"/>
 <xs:include schemaLocation="msml-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-audit-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-audit-dialog-datatypes.xsd"/>
 <xs:include schemaLocation="msml-audit-stream-datatypes.xsd"/>
 <xs:include schemaLocation="msml-audit-conf-datatypes.xsd"/>
</xs:schema>

16.4.4. msml-audit-conf-datatypes.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-conf-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-audit-core-datatypes.xsd"/>
 <xs:element name="confconfig" substitutionGroup="stateParameter">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="stateParameterType">
     <xs:sequence>
      <xs:element name="audiomix" type="audioMixType" minOccurs="0"
                  maxOccurs="unbounded"/>

      <xs:element name="videolayout" type="videoLayoutType"
                  minOccurs="0" maxOccurs="unbounded"/>
      <xs:element name="controller" type="connID.datatype"
                  minOccurs="0"/>
     </xs:sequence>
     <xs:attribute name="deletewhen" use="optional" default="never">
      <xs:simpleType>
       <xs:restriction base="xs:string">
        <xs:enumeration value="nomedia"/>
        <xs:enumeration value="nocontrol"/>
        <xs:enumeration value="never"/>
       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="term" type="boolean.datatype" use="optional"
                   default="true"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
</xs:schema>

16.4.5. msml-audit-conn.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-core.xsd"/>
 <xs:include schemaLocation="msml-audit-core-datatypes.xsd"/>
 <xs:include schemaLocation="msml-audit-dialog-datatypes.xsd"/>
 <xs:include schemaLocation="msml-audit-stream-datatypes.xsd"/>
 <xs:include schemaLocation="msml-audit-conn-datatypes.xsd"/>
</xs:schema>

16.4.6. msml-audit-conn-datatypes.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-audit-core-datatypes.xsd"/>
 <xs:element name="sipdialog" substitutionGroup="stateParameter">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="stateParameterType">
     <xs:sequence>
      <xs:element name="localseq" type="xs:integer" minOccurs="0"/>
      <xs:element name="remoteseq" type="xs:int" minOccurs="0"/>
      <xs:element name="localuri" type="xs:string" minOccurs="0"/>
      <xs:element name="remoteuri" type="xs:string" minOccurs="0"/>
      <xs:element name="remotetarget" type="xs:string" minOccurs="0"/>
      <xs:element name="routeset" type="xs:string" minOccurs="0"/>
     </xs:sequence>
     <xs:attribute name="callid" type="xs:string" use="required"/>
     <xs:attribute name="localtag" type="xs:string" use="required"/>
     <xs:attribute name="remotetag" type="xs:string" use="required"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
 <xs:element name="localsdp" type="stateParameterSimpleType"
             substitutionGroup="stateParameterSimple"/>
 <xs:element name="remotesdp" type="stateParameterSimpleType"
             substitutionGroup="stateParameterSimple"/>
</xs:schema>

16.4.7. msml-audit-dialog-datatypes.xsd โœจ

okay so Audit Dialog stuff needs either the Audit Conf Package or the Audit Conn Package, bestie ๐Ÿ’–

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-audit-core-datatypes.xsd"/>
 <xs:element name="dialog" substitutionGroup="stateParameter">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="stateParameterType">
     <xs:sequence>
      <xs:element name="duration" type="xs:positiveInteger"
                  minOccurs="0"/>
      <xs:element name="primitive" minOccurs="0">
       <xs:simpleType>
        <xs:restriction base="xs:string">
         <xs:pattern value="play"/>
         <xs:pattern value="dtmf"/>
         <xs:pattern value="collect"/>
         <xs:pattern value="dtmfgen"/>
         <xs:pattern value="tonegen"/>
         <xs:pattern value="record"/>
         <xs:pattern value="none"/>
        </xs:restriction>
       </xs:simpleType>

      </xs:element>
      <xs:element name="controller" type="connID.datatype"
                  minOccurs="0"/>
     </xs:sequence>
     <xs:attribute name="name" type="msmlInstanceID.datatype"
                   use="required"/>
     <xs:attribute name="src" type="xs:anyURI" use="optional"/>
     <xs:attribute name="type" type="dialogLanguage.datatype"
                   use="required"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
</xs:schema>

16.4.8. msml-audit-stream-datatypes.xsd ๐ŸŽ€

Audit Stream functionality needs either the Audit Conf Package or the Audit Conn Package too, so same energy as the dialog schema ๐Ÿซถ

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
 <xs:include schemaLocation="msml-audit-core-datatypes.xsd"/>
 <xs:element name="stream" substitutionGroup="stateParameter">
  <xs:complexType>
   <xs:complexContent>
    <xs:extension base="stateParameterType">
     <xs:all>
      <xs:element name="clamp" minOccurs="0">
       <xs:complexType>
        <xs:attribute name="dtmf" type="boolean.datatype"/>
        <xs:attribute name="tones" type="boolean.datatype"/>
       </xs:complexType>
      </xs:element>
      <xs:element name="gain" minOccurs="0">
       <xs:complexType>
        <xs:attribute name="amt" use="optional">
         <xs:simpleType>
          <xs:restriction base="xs:integer">
           <xs:minInclusive value="-96"/>
           <xs:maxInclusive value="96"/>
          </xs:restriction>
         </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="agc" type="boolean.datatype"/>
        <xs:attribute name="tgtlvl" use="optional">

         <xs:simpleType>
          <xs:restriction base="xs:nonPositiveInteger">
           <xs:minInclusive value="-40"/>
           <xs:maxInclusive value="0"/>
          </xs:restriction>
         </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="maxgain" default="10">
         <xs:simpleType>
          <xs:restriction base="xs:nonNegativeInteger">
           <xs:minInclusive value="0"/>
           <xs:maxInclusive value="40"/>
          </xs:restriction>
         </xs:simpleType>
        </xs:attribute>
       </xs:complexType>
      </xs:element>
      <xs:element name="visual" minOccurs="0"/>
     </xs:all>
     <xs:attribute name="joinwith" type="independentID.datatype"
                   use="required"/>
     <xs:attribute name="media" use="required">
      <xs:simpleType>
       <xs:restriction base="xs:string">
        <xs:pattern value="audio"/>
        <xs:pattern value="video"/>
       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="dir" use="required">
      <xs:simpleType>
       <xs:restriction base="xs:string">
        <xs:pattern value="from"/>
        <xs:pattern value="to"/>
       </xs:restriction>
      </xs:simpleType>
     </xs:attribute>
     <xs:attribute name="compressed" type="boolean.datatype"/>
     <xs:attribute name="preferred" type="boolean.datatype"
                   default="false"/>
     <xs:attribute name="display" type="xs:string"/>
     <xs:attribute name="override" type="boolean.datatype"
                   default="false"/>
    </xs:extension>
   </xs:complexContent>
  </xs:complexType>
 </xs:element>
</xs:schema>

17. Security Considerations ๐Ÿ”

bestie, this part is serious, so listen up ๐Ÿ‘‘ MSML is an XML-based language, which means the security considerations from RFC 3023 [i2] apply to it. ๐Ÿ˜ญ

Media server interfaces that MSML drives are under the explicit control of a SIP application server. SIP call legs are what carry the XML-based MSML transactions over to the media server. For the security and integrity of MSML transactions, whenever they are needed, you SHOULD use sips: and TLS to encrypt and authenticate the SIP control channel that carries the MSML payloads. More info on the security, privacy, and integrity of the MSML media types lives in the IANA Considerations section ๐Ÿฆ‹

Media streams, like audio/video, MAY optionally be protected, encrypted/decrypted, and authenticated with Secure Real Time Protocol (SRTP), wherever media stream security is needed. Media negotiation sets the required level of security and is started by the clients. That part is outside the scope of the control interface MSML specifies, so it's not MSML's job ๐Ÿ’…


18. IANA Considerations ๐ŸŒˆ

18.1. IANA Registrations for 'application' MIME Media Type ๐Ÿ’œ

The following registrations have been made:

Type Name: "application"

Subtype names:

'application/vnd.radisys.msml+xml',
'application/vnd.radisys.moml+xml',
'application/vnd.radisys.msml-conf+xml',
'application/vnd.radisys.msml-dialog+xml',
'application/vnd.radisys.msml-dialog-base+xml',
'application/vnd.radisys.msml-dialog-group+xml',
'application/vnd.radisys.msml-dialog-speech+xml',
'application/vnd.radisys.msml-dialog-transform+xml',
'application/vnd.radisys.msml-dialog-fax-detect+xml',
'application/vnd.radisys.msml-dialog-fax-sendrecv+xml',
'application/vnd.radisys.msml-audit+xml',
'application/vnd.radisys.msml-audit-conf+xml',
'application/vnd.radisys.msml-audit-conn+xml',
'application/vnd.radisys.msml-audit-dialog+xml',
'application/vnd.radisys.msml-audit-stream+xml'

Required parameters: none

Optional parameters: charset

charset semantics as specified in RFC 3023 [i2] for "application/xml" media type.

Encoding considerations:

As specified in RFC 3023 [i2].

Security Considerations:

Media types included in this section are XML based, so security considerations as defined by RFC 3023 [i10] apply to them. ๐Ÿ™ˆ

These media types don't have any active or executable content, because the content itself just controls the underlying media streams ๐Ÿ’–

Secure exchange of content tied to these media types, for authentication and privacy whenever that applies, shall require setting up a secure control channel with sips: and TLS.

Privacy and integrity of media content tied to these media types need thinking about when apps using them swap personal info, like personal identification codes or conference access codes. Whenever that content needs secure transport and authentication, a secure channel using sips: and TLS MUST be used, because these media types don't provide any built-in security mechanisms of their own. This part is non-negotiable, bestie ๐Ÿšจ

Interoperability considerations:

As specified in RFC 3023 [i2] and as specified within this document.

Published specification: RFC 5707

Intended applications for these media types:

Multimedia Conferencing, Interactive Voice Response systems

Additional information:

Magic number(s): None

File extension(s): None

Macintosh file type code(s): None

Person & email address to contact for further information:

Adnan Saleem <adnan.saleem@radisys.com>

Intended usage: COMMON

18.2. IANA Registrations for 'text' MIME Media Type ๐Ÿ“

The following registrations are planned:

text/vnd.radisys.msml-basic-layout

Required parameters: none

Optional parameters: charset

charset semantics as specified in RFC 3023 [i2] for "text/xml" media type.

Encoding considerations: As specified in RFC 3023 [i2].

Security Considerations:

Media types included in this section are XML based, so security considerations as defined by RFC 3023 [i10] apply to them. ๐Ÿ™ˆ

The media type defined in this section doesn't have any active or executable content. It only defines a visual layout scheme for a video conference. Setting up the active connections tied to the video conference is outside the scope of this media type ๐ŸŽ€

Since this media type only defines a visual layout scheme, with no reference or information about client connections or participants within the conference, privacy and integrity concerns don't apply to it โœจ

Interoperability considerations:

As specified in RFC 3023 [i2] and as specified within this document.

Published specification: RFC 5707

Intended applications for these media types:

Multimedia Conferencing, Interactive Voice Response systems

Additional information:

Magic number(s): None

File extension(s): None

Macintosh file type code(s): None

Person & email address to contact for further information:

Adnan Saleem <adnan.saleem@radisys.com>

Intended usage: COMMON

18.3. URN Sub-Namespace Registration ๐Ÿงš

The namespace URI for elements defined in this specification is a URN [i8]. It uses the namespace identifier 'ietf' defined by [i9] and extended by RFC 3688 [i10].

The following registrations of URN Sub-Namespaces are planned:

XML namespace: urn:ietf:params:xml:ns:msml

XML:

BEGIN

<?xml version="1.0"?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN"

"http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

  <head>

      <meta http-equiv="content-type"

            content="text/html;charset=iso-8859-1"/>

      <title>Media Server Markup Language Namespace</title>

  </head>

  <body>

     <h1>Namespace for Media Server Markup Language</h1>

     <h2>urn:ietf:params:xml:ns:msml</h2>

     <p>See MSML <a
    href="http://www.rfc-editor.org/rfc/rfc5707.txt">RFC 5707</a></p>

  </body>

</html>

END

18.4. XML Schema Registration ๐Ÿ’–

This section registers an XML schema per the procedures in [i10].

URI: urn:ietf:params:xml:schema:msml

Registrant Contact:

Adnan Saleem (adnan.saleem@radisys.com) and authors listed within this document.

The XML for this schema can be found as the sole content of Section 16. ๐ŸŒธ


19. References ๐Ÿ“š

19.1. Normative References โœจ

okay bestie, these are the must-reads ๐Ÿ“š Everything here is required reading to understand the spec, no skipping!

[n1] Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston, A., Peterson, J., Sparks, R., Handley, M., and E. Schooler, "SIP: Session Initiation Protocol", RFC 3261, June 2002. ๐Ÿ“ž

[n2] Bray, T., Paoli, J., Sperberg-McQueen, C., and E. Maler, "Extensible Markup Language (XML) 1.0 (Second Edition)," W3C First Edition REC-xml-20001006, October 2000. ๐Ÿงพ

[n3] World Wide Web Consortium, "Speech Recognition Grammar Specification Version 1.0" (SRGS), W3C Candidate Recommendation, March 16, 2004 ๐ŸŽ™๏ธ

[n4] World Wide Web Consortium, "Natural Language Semantics Markup Language (NLSML) for the Speech Interface Framework", W3C Working Draft 20, November 2000. ๐Ÿ’ฌ

[n5] World Wide Web Consortium, "Voice Extensible Markup Language (VoiceXML) Version 2.0, W3C Candidate Recommendation, March 16, 2004. ๐Ÿ—ฃ๏ธ

[n6] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, January 2005. ๐Ÿ”—

[n7] Burger, E., Ed., Van Dyke, J., and A. Spitzer, "Basic Network Media Services with SIP", RFC 4240, December 2005. ๐ŸŽฌ

[n8] Levinson, E., "Content-ID and Message-ID Uniform Resource Locators", RFC 2392, August 1998. ๐Ÿท๏ธ

[n9] Handley, M., Jacobson, V., and C. Perkins, "SDP: Session Description Protocol", RFC 4566, July 2006. ๐Ÿงฉ

[n10] Bos, B., Lie, H., Tantek, C., and Hickson, I., "Cascading Style Sheets, level 2 (CSS2) Specification," W3C REC CR-CSS21-, July 2007. ๐Ÿ’…

[n11] Burnett, D., Walker, M., and Hunt, A., "Speech Synthesis Markup Language (SSML) Version 1.0", W3C Recommendation, 7 September 2004. ๐Ÿ”Š

19.2. Informative References ๐Ÿ’–

these ones are the extra-credit reading, totally worth a look if you wanna go deeper ๐Ÿค“

[i1] Rosenberg, J., Schulzrinne, H., and P. Kyzivat, "Indicating User Agent Capabilities in the Session Initiation Protocol (SIP)", RFC 3840, August 2004. ๐Ÿชช

[i2] Murata, M., St. Laurent, S., and D. Kohn, "XML Media Types", RFC 3023, January 2001. ๐Ÿท๏ธ

[i3] Schulzrinne, H., Casner, S., Frederick, R., and V. Jacobson, "RTP: A Transport Protocol for Real-Time Applications", STD 64, RFC 3550, July 2003. ๐ŸŽฅ

[i4] Rosenberg, J., Peterson, J., Schulzrinne, H., and G. Camarillo, "Best Current Practices for Third Party Call Control (3pcc) in the Session Initiation Protocol (SIP)", BCP 85, RFC 3725, April 2004. ๐Ÿค

[i5] Donovan, S., "The SIP INFO Method", RFC 2976, October 2000. โ„น๏ธ

[i6] Ossenbruggen, J., Rutledge, L., Saccocio, B., Schmitz, P., Kate, W., Ayars, J., Bulterman, D., Cohen, A., Day, K., Hodge, E., Hoschka, P., Hyche, E., Jourdan, M., Kubota, K., Lanphier, R., Laya'da, N., Michel, T., and D. Newman, "Synchronized Multimedia Integration Language (SMIL 2.0) Specification," W3C REC REC-smil2-20050107, January 2005. ๐ŸŽž๏ธ

[i7] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types", RFC 2046, November 1996. ๐Ÿ“Ž

[i8] Moats, R., "URN Syntax", RFC 2141, May 1997. ๐Ÿช„

[i9] Moats, R., "A URN Namespace for IETF Documents", RFC 2648, August 1999. ๐Ÿ—‚๏ธ

[i10] Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688, January 2004. ๐Ÿ“‹

[i11] Boulton, C., Melanchuk, T., McGlashan, S., and A. Shiratzky, "A Control Framework for the Session Initiation Protocol (SIP)", Work in Progress, February 2007. ๐Ÿšง

Acknowledgments ๐Ÿซถ

the squad that made this whole thing possible, literally iconic of them ๐Ÿ‘‘

Sergiu Stambolian of RadiSys provided key insights, both theoretic and through development experience, on several versions of the document. ๐Ÿง 

Stephen Buko and George Raskulinec of Intel made numerous valuable contributions towards enhancements of multimedia playback and record operations. ๐ŸŽถ

Gene Shtirmer of Intel provided review feedback on several revisions and feature enhancement suggestions. ๐Ÿ“

David Asher of NMS Communications provided valuable insights towards creation of standard profiles and a modularization scheme based on packages for better interoperability. ๐Ÿงฉ

Gilles Compienne of Ubiquity Software has provided feedback on several earlier versions of this document. ๐Ÿ’œ

Chris Boulton and Ben Smith, both of Ubiquity, and Michael Rice of VocalData helped clarify several issues, while Bruce Walsh and Kevin Fitzgerald, both of Spectel/Avaya, provided important feedback. โœจ

Cliff Schornak of Commetrex significantly contributed to the facsimile work. ๐Ÿ“ 

Peter Danielsen of Lucent has contributed thoughtful and detailed reviews for several earlier versions of the document. ๐ŸŒธ

Authors' Addresses ๐ŸŽ€

these are the brains behind it, so you know where to find them ๐Ÿฆ‹

Adnan Saleem RadiSys 4190 Still Creek Drive, Suite 300 Burnaby, BC, V5C 6C6 Canada

Phone: +1 604 918 6376 EMail: adnan.saleem@radisys.com

Yong Xin RadiSys 4190 Still Creek Drive, Suite 300 Burnaby, BC, V5C 6C6 Canada

Phone: +1 604 918 6383 EMail: yong.xin@radiSys.com

Garland Sharratt Consultant Vancouver, BC Canada

EMail: garland.sharratt@gmail.com

and that's a wrap, bestie! ๐ŸŒˆ๐Ÿ’…โœจ

๐Ÿ“ฆ where this page comes from