RFC 5022
Media Server Control Markup Language (MSCML) and Protocol
Part 1 of 17 π
Media Server Control Markup Language (MSCML) and Protocol π
Okay bestie, this is RFC 5022, and it's all about the Media Server Control Markup Language (MSCML) and Protocol β¨ It was written by J. Van Dyke (Cantata Technology, Inc.), E. Burger, Ed. (BEA Systems, Inc.), and A. Spitzer (Bluesocket Inc.), and it came out in September 2007. It's Informational π¦, which means it's not a standards-track doc. It obsoletes RFC 4722, and the title block doesn't list anything it updates.
Status of This Memo πΈ
This memo provides information for the Internet community. It does not specify an Internet standard of any kind. Distribution of this memo is unlimited.
IESG Note π
ngl, this one's a little serious. This RFC is not a candidate for any level of Internet Standard. The IETF disclaims any knowledge of the fitness of this RFC for any purpose, and in particular it notes that 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 document at its discretion. Readers should exercise caution in evaluating its value for implementation and deployment. See RFC 3932 for more information.
Abstract π§
MSCML is a markup language used together with SIP to unlock advanced conferencing and interactive voice response (IVR) functions π§ It's an application-level control model, not a device-level one, so you're thinking about things like calls and conferences rather than the low-level nitty-gritty. One use of this protocol is communication between a conference focus and mixer in the IETF SIP Conferencing Framework.
Table of Contents π
1. Introduction ....................................................4
1.1. Conventions Used in This Document ..........................5
2. MSCML Approach ..................................................5
3. Use of SIP Request Methods ......................................6
4. MSCML Design ....................................................8
4.1. Transaction Model ..........................................8
4.2. XML Usage ..................................................9
4.2.1. MSCML Time Values ...................................9
5. Advanced Conferencing ..........................................10
5.1. Conference Model ..........................................10
5.2. Configure Conference Request <configure_conference> .......11
5.3. Configure Leg Request <configure_leg> .....................13
5.4. Terminating a Conference ..................................14
5.5. Conference Manipulation ...................................15
5.6. Video Conferencing ........................................16
5.7. Conference Events .........................................17
5.8. Conferencing with Personalized Mixes ......................18
5.8.1. MSCML Elements and Attributes for
Personalized Mixes .................................19
5.8.2. Example Usage of Personalized Mixes ................20
6. Interactive Voice Response (IVR) ...............................23
6.1. Specifying Prompt Content .................................24
6.1.1. Use of the Prompt Element ..........................24
6.2. Multimedia Processing for IVR .............................30
6.3. Playing Announcements <play> ..............................31
6.4. Prompt and Collect <playcollect> ..........................32
6.4.1. Control of Digit Buffering and Barge-In ............33
6.4.2. Mapping DTMF Keys to Special Functions .............33
6.4.3. Collection Timers ..................................35
6.4.4. Logging Caller DTMF Input ..........................36
6.4.5. Specifying DTMF Grammars ...........................36
6.4.6. Playcollect Response ...............................37
6.4.7. Playcollect Example ................................38
6.5. Prompt and Record <playrecord> ............................38
6.5.1. Prompt Phase .......................................38
6.5.2. Record Phase .......................................39
6.5.3. Playrecord Example .................................41
6.6. Stop Request <stop> .......................................42
7. Call Leg Events ................................................43
7.1. Keypress Events ...........................................43
7.1.1. Keypress Subscription Examples .....................45
7.1.2. Keypress Notification Examples .....................45
7.2. Signal Events .............................................46
7.2.1. Signal Event Examples ..............................47
8. Managing Content <managecontent> ...............................48
8.1. Managecontent Example .....................................50
9. Fax Processing .................................................51
9.1. Recording a Fax <faxrecord> ...............................51
9.2. Sending a Fax <faxplay> ...................................53
10. MSCML Response Attributes and Elements ........................56
10.1. Mechanism ................................................56
10.2. Base <response> Attributes ...............................56
10.3. Response Attributes and Elements for <configure_leg> .....57
10.4. Response Attributes and Elements for <play> ..............57
10.4.1. Reporting Content Retrieval Errors ...............58
10.5. Response Attributes and Elements for <playcollect> .......59
10.6. Response Attributes and Elements for <playrecord> ........60
10.7. Response Attributes and Elements for <managecontent> .....61
10.8. Response Attributes and Elements for <faxplay>
and <faxrecord> ..........................................61
11. Formal Syntax .................................................62
11.1. Schema ...................................................62
12. IANA Considerations ...........................................73
12.1. IANA Registration of MIME Media Type application/
mediaservercontrol+xml ...................................73
13. Security Considerations .......................................74
14. References ....................................................75
14.1. Normative References .....................................75
14.2. Informative References ...................................76
Appendix A. Regex Grammar Syntax .................................78
Appendix B. Contributors .........................................79
Appendix C. Acknowledgements .....................................79
1. Introduction β¨
This doc describes MSCML and how you use it π It covers the payloads you can send to a media server using standard SIP INVITE and INFO methods, plus the capabilities those payloads implement. RFC 4240 [2] describes media server SIP URI formats.
So, before MSCML, there wasn't a standard way to do SIP-based enhanced conferencing π Basic SIP stuff, like what's described in RFC 4240 [2], handles simple n-way conferencing really well. The SIP URI is a natural way to identify a specific SIP conference, and INVITE and BYE methods handle joining and leaving super elegantly. But enhanced conferencing apps also need things like sizing and resizing, in-conference IVR operations (like recording and playing participant names to the full conference), and conference event reporting. MSCML payloads inside standard SIP methods make all of that happen π¦
The structure and approach of MSCML satisfy the requirements set out in RFC 4353 [10]. Specifically, MSCML is the interface between the conference server or focus and a centralized conference mixer. In this setup, a media server plays the role of the conference mixer π
There are two broad classes of MSCML functionality. The first class is the advanced conferencing stuff, like conference configuration, participant leg manipulation, and conference event reporting. The second class is primitives for interactive voice response (IVR), which means collecting DTMF digits and playing and recording multimedia content π§
MSCML handles IVR and conference control with requests and responses over a SIP transport. VoiceXML [11] handles IVR with requests and responses over a HTTP transport. This means developers can pick whatever model fits their needs best π
In general, a media server offers services to SIP UACs, such as Application Servers, Feature Servers, and Media Gateway Controllers. See the IPCC Reference Architecture [12] for definitions of these terms. It's unlikely, but not prohibited, for end-user SIP UACs to have a direct signaling relationship with a media server. In this document, the term "client" is used generically to mean any entity that interacts with the media server using SIP and MSCML π«Ά
The media server fills the role of the Media Resource Function (MRF) in the IP Multimedia Subsystem (IMS) [13], as described by 3GPP. MSCML, and RFC 4240 [2] which MSCML builds on, are specifically focused on the Media resource (Mr) interface, which supports interactions between application logic and the MRF π
This document describes a working framework and protocol with a lot of real implementation experience behind it π₯ Application developers and service providers have built several MSCML-based services since the initial version became available in 2001. This experience is highly relevant to ongoing work at the IETF, especially in the SIP [26], SIPPING [27], MMUSIC [28], and XCON [29] work groups, the IMS [30] work in 3GPP, and the CCXML work in the Voice Browser Work Group of the W3C.
1.1. Conventions Used in This Document π
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [1].
2. MSCML Approach π§
It's critically important to get this: the goal of MSCML is to provide an application interface that follows the SIP, HTTP, and XML development paradigm, so apps get deployed faster and easier π That goal shows up in MSCML in two ways.
First, the programming model is peer to peer, not master-slave π€ This is a big deal because it lets the media server be used by multiple applications at once, instead of being tied to a single point of control. It also means standard SIP mechanisms can be used for media server location and load balancing.
Second, MSCML defines constructs and primitives that are meaningful at the application level, so programmers aren't distracted by unnecessary complexity π For example, the mixing resource works on constructs like conferences and call participants, rather than directly on individual media streams.
The MSCML paradigm matters to the developer community, since developers and operators conceptually write applications about calls, conferences, and call legs. For most developers and applications, this approach really simplifies and speeds up development π
3. Use of SIP Request Methods β¨
okay so bestie, MSCML payloads can ride along in either a SIP INVITE or a SIP INFO request π¦ The initial INVITE that makes an enhanced conference MAY include an MSCML payload. A later INVITE to that same Request-URI joins a participant leg to the conference, and that one MAY include an MSCML payload too. The initial INVITE that sets up an IVR session MUST NOT include an MSCML payload. All mid-call MSCML payloads for conferencing and IVR go out via SIP INFO requests π
INVITE requests that carry both MSCML and Session Description Protocol (SDP) body parts show up a LOT in conferencing, so the media server MUST support message bodies with the MIME type "multipart/mixed" in SIP INVITE requests. Non-negotiable, periodt π
The media server sends MSCML responses in the final response to the SIP INVITE that had the matching MSCML request, or in a SIP INFO message. The only allowable final response to a SIP INFO with a message body is a 200 OK, per RFC 2976 [3]. So if the client sent the MSCML request via SIP INFO, the media server replies with the MSCML response in a separate INFO request πΈ These responses are async by nature and need their own transaction because of timing, so yeah, that's just how it goes π§
There's been a LOT of debate about using SIP INFO for anything, ngl π But honestly? MSCML wouldn't have been possible without it. When the first MSCML spec dropped, the first SIP Event Notification draft had only just been submitted as an individual submission. Back then there was no way to link SUBSCRIBE/NOTIFY to an existing dialog, and since every MSCML event happens inside an INVITE-established dialog, that was a dealbreaker π SUBSCRIBE/NOTIFY was great for reporting conference events, but its semantics felt off for modifying a participant leg or conference setting, where the only "event" is whether the request worked or not. Plus SIP INFO was already an established RFC, so most SIP stacks supported it, and we had few, if any, interop issues π
More recent developments give even more reasons why SUBSCRIBE/NOTIFY isn't the move for MSCML. SUBSCRIBE has two problems. The first is semantic: SUBSCRIBE is meant to register interest in User Agent state, but using it for MSCML means the SUBSCRIBE actually modifies the User Agent state, which is so not the vibe π€ The second is that MSCML is inherently call based. Tying a SIP dialog to a call leg makes MSCML incredibly straightforward β¨
Like, if you used SUBSCRIBE or some other SIP method to send commands about some context, you'd have to identify that context somehow. But relating commands to the SIP dialog they arrive on defines the context for free π¦ It's also just conceptually easy for the developer, which is a big win π And using NOTIFY to carry MSCML responses is also a no-go, because the NOTIFY would be responding to an implicit subscription, and the SIP and SIPPING lists have discussed the dangers of implicit subscription π
To guarantee interoperability with this specification, and with SIP User Agents that have no idea what MSCML is, SIP UACs that want MSCML services MUST specify a service indicator that supports MSCML in the initial INVITE. RFC 4240 [2] defines the service indicator "conf", which MUST be used for MSCML conferencing applications. The service indicator "ivr" MUST be used for MSCML interactive voice response applications. In this spec, only "conf" and "ivr" are described π
The media server MUST support moving a call between services by sending the media server a BYE on the existing dialog and then establishing a new dialog with an INVITE to the desired service. Media servers SHOULD support moving between services without modifying the previously established SDP parameters. This is done with a re-INVITE on the existing dialog where the Request-URI is changed to name the new service the client wants. That way the client doesn't need to send an INVITE to the caller or gateway to set up new SDP parameters, which is honestly so efficient π«Ά
The media server, acting as a SIP UAS, MUST respond appropriately to an INVITE that contains an MSCML body. If MSCML isn't supported, the media server MUST generate a 415 final response and include a list of the supported content types in the response, per RFC 3261 [4]. The media server MUST also advertise its MSCML support in responses to OPTIONS requests, by including "application/mediaservercontrol+xml" as a supported content type in an Accept header. This fixes the biggest headache with using INFO for application data, which is that the User Agent has to correctly interpret what is, by design, an opaque message request π
4. MSCML Design π
4.1. Transaction Model
okay so to keep things from getting messy π§, MSCML has two rules. First, only one MSCML body may be present in a SIP request. Second, each MSCML body may contain only one request or response. This makes transaction management SO much simpler β¨ MSCML syntax can actually uniquely identify multiple requests inside a single body part, but this spec doesn't support that π
Per the guidelines of RFC 3470 [14], MSCML bodies MUST be well formed and valid. No messy XML allowed, bestie π
MSCML is a direct request-response protocol. There are no provisional responses, only final responses π¦ A request can still result in multiple notifications, though. For example, a request for active talker reports gives you a notification for each speaker set π This maps onto the three major element trees in MSCML: <request>, <response>, and <notification>.
Figure 1 shows a request body. Depending on the command, you can send the request in an INVITE or an INFO. Figure 2 shows a response body, which the SIP INFO method transports. Figure 3 shows a notification body, which SIP INFO also transports πΈ
<?xml version="1.0" encoding="utf-8"?>
<MediaServerControl version="1.0">
<request>
... request body ...
</request>
</MediaServerControl>
Figure 1: MSCML Request Format
<?xml version="1.0" encoding="utf-8"?>
<MediaServerControl version="1.0">
<response>
... response body ...
</response>
</MediaServerControl>
Figure 2: MSCML Response Format
<?xml version="1.0" encoding="utf-8"?>
<MediaServerControl version="1.0">
<notification>
... notification body ...
</notification>
</MediaServerControl>
Figure 3: MSCML Notification Format
MSCML requests MAY include a client-defined ID attribute so requests and responses can be matched up π₯ The values for these IDs only need to be unique within the scope of the dialog the requests are sent in π
4.2. XML Usage
In the philosophy of XML as a text-based description language, and not as a programming language, MSCML picks attribute values that humans can read easily π So a lot of attributes that would normally be "boolean" take "yes" or "no" instead. Like, what does 'report="false"' or 'report="1"' even mean? π But 'report="yes"' is clear: I want a report! Some programmers love the precision of a boolean though, so to make everyone happy, MSCML defines an XML type, "yesnoType", that accepts "yes" and "no" as well as "true", "false", "1", and "0" π
Many attributes in the MSCML schema have default values. To limit demands on the XML parser, MSCML applies these defaults at the protocol level, not the XML level π§ The MSCML schema documents these defaults as XML annotations on the appropriate attribute β¨
4.2.1. MSCML Time Values
For clarity, time values in MSCML are based on the time designations from the Cascading Style Sheets level 2 (CSS2) Specification [15] π The format is a number immediately followed by an optional time unit identifier, like this:
ms: milliseconds (default)
s: seconds
If no time unit identifier is present, the value MUST be interpreted as milliseconds πΈ As extensions to [15], MSCML allows the string values "immediate" and "infinite", which have special meaning for certain timers π¦
5. Advanced Conferencing π
5.1. Conference Model π
Okay so the advanced conferencing model is a star controller model, bestie. Signaling AND media both go to one central spot π Figure 4 shows how the end users' UACs, a conference application server, and a media server all talk to each other.
RFC 4353 [10] describes this model. The application server is the conference focus, and the media server is the media mixer π§ User-level stuff like event notifications belongs to the application server. So the media server sends active talker reports using MSCML notifications, but the application server uses the conference package [16] for individual notifications to SIP user agents. And we do NOT recommend using the conference package for media server to application server notifications, because the media server has zero access to the filtering and membership info π
+-------+
| UAC 1 |---\ Public URI +-------------+
+-------+ \ _____________| Application |
/ / | Server | Not shown:
+-------+ / / +-------------+ RTP flows directly
| UAC 2 |---/ / | Private between UACs and
+-------+ / | URI media server
. / +--------------+
: / | |
+-------+ / | Media Server |
| UAC n |---/ | |
+-------+ +--------------+
Figure 4: Conference Model
Every UAC sends an INVITE to a Public Conference URI. The client probably publishes that URI, or it's an ad hoc one, whatever π¦ Either way, the client generates a Private URI following the rules in RFC 4240 [2]. It looks like this:
sip:conf=UniqueID@ms.example.net
where UniqueID is a unique conference identifier, and ms.example.net is the host name or IP address of the media server πΈ Nothing stops the UACs from contacting the media server directly, ngl. Still, you'd expect the media server's owner to restrict who gets to use its resources. Main character energy for the owner π
Basic conferencing (RFC 4240 [2]) works like this: the first INVITE to the media server with a UniqueID creates a conference. In advanced conferencing, though, the first INVITE MAY include a MSCML <configure_conference> payload instead of a conference participant's SDP. That payload carries extended session parameters, like the number of participants, which SDP can't really express. The media server NEEDS to know this stuff so it can allocate the right resources β¨
When the conference gets created with an INVITE that has a MSCML <configure_conference> payload, the resulting SIP dialog is called the "Conference Control Leg." It has some seriously useful perks π«Ά The conference lives exactly as long as its control leg does. So the conference stays alive even if every participant leg leaves, or hasn't shown up yet. And if the client terminates the Conference Control Leg, the media server automatically terminates all the participant legs. The Conference Control Leg is also used for play or record operations to and from the entire conference, plus active talker notifications. Full conference media operations and active talker report subscriptions MUST be executed on the Conference Control Leg, no exceptions π₯
Creating a Conference Control Leg is RECOMMENDED, because full advanced conferencing capabilities aren't available without it π Clients MUST establish the Conference Control Leg in the initial INVITE that creates the conference. It cannot be created later, so don't forget it π
Once the client has created the conference, with or without the Conference Control Leg, participants can join. The client directs an INVITE to the Private Conference URI for each participant. Using the example conference URI from above, that would be sip:conf=UniqueID@ms.example.net.
5.2. Configure Conference Request <configure_conference> π
The <configure_conference> request has two attributes that control how many resources the media server sets aside for the conference. Here they are:
Attributes of <configure_conference>:
reservedtalkers- optional (see note), no default value: The maximum number of talker legs allocated for the conference. Note: required when establishing the Conference Control Leg, but optional in subsequent<configure_conference>requests.reserveconfmedia- optional, default value "yes": Controls allocation of resources so you can play or record to or from the entire conference.
When the reservedtalkers+1st INVITE arrives at the media server, the media server SHOULD generate a 486 Busy Here response. If it doesn't send that 486, the media server can end up oversubscribing its resources, and that's a whole mess π
NOTE: It would be symmetric to have a reservedlisteners parameter. However, the practical limitation on the media server is the number of talkers for a mixer to monitor. In either case, the client regulates who gets into the conference by either proxying the INVITEs from the user agent clients or metering to whom it gives the conference URI.
Say the client wants a conference with up to 120 active talkers, plus the ability to play audio into the conference or record some or all of the conference full mix. Then it specifies both attributes, like in Figure 6 β¨
<?xml version="1.0" encoding="utf-8"?>
<MediaServerControl version="1.0">
<request>
<configure_conference reservedtalkers="120"
reserveconfmedia="yes"/>
</request>
</MediaServerControl>
Figure 6: 120 Speaker MSCML Example
Besides those attributes, a <configure_conference> request MAY contain a child <subscribe> element. That element requests notifications for conference-wide active talker events. You can find the details about those events in Section 5.7 π§
The client MUST include a <configure_conference> request in the initial INVITE that establishes the conference when it creates the Conference Control Leg. The client server MUST issue asynchronous commands, such as <play>, separately (i.e., in INFO messages) to avoid ambiguous responses π
Media operations on the Conference Control leg happen internally. No external RTP streams are involved, so the media server doesn't expect RTP on the Conference Control Leg. That's why the client MUST send either no SDP or hold SDP in the INVITE request that carries a <configure_conference> payload. The media server MUST treat SDP as hold SDP when all media lines are set to "inactive", or when connection addresses are set to 0.0.0.0 (for backwards compatibility) π¦
The media server sends a response once it's finished processing the <configure_conference> request. The format of that response is detailed in Section 10.2.
5.3. Configure Leg Request <configure_leg> π
Conference legs have a bunch of properties the client can change, and it does that with the <configure_leg> request. This request has the attributes described below π§
Attributes of <configure_leg>:
type- optional, default value "talker": Considers this leg's audio for inclusion in the output mix. The alternative is "listener".dtmfclamp- optional, default value "yes": Removes detected DTMF digits from the input audio.toneclamp- optional, default value "yes": Removes tones from the input audio. Tones include call progress tones and the like.mixmode- optional, default value "full": Makes this leg a candidate for the full mix. The alternatives are "mute", which disallows media in the mix; "parked", which disconnects the leg's media streams from the conference for IVR operations; "preferred", which gives this stream preferential selection in the mix (so even if it's not the loudest talker, its media gets included if it's present); and "private", which enables personalized mixes.
Besides those attributes, <configure_leg> has four child elements: <inputgain>, <outputgain>, <configure_team>, and <subscribe> β¨
The first two, <inputgain> and <outputgain>, change the gain on the input and output audio streams, respectively. Each can contain <auto> (to use automatic gain control, AGC) or <fixed>. The <auto> element has the attributes "startlevel", "targetlevel", and "silencethreshold", and all of those parameters are in dB. The <fixed> element has the attribute "level", also in dB. The default for both <inputgain> and <outputgain> is <fixed>. The media server MAY silently cap <inputgain> or <outputgain> requests that go over the gain limits the platform imposes π
Clients mostly just tweak the input gain for a conference leg and let the mixer pick a good output gain based on the inputs currently in the mix. But as described above, MSCML does let you manipulate the output gain too. Some of the IVR commands, like <play>, let you control the output gain for content playback. How conference output gain and IVR playback gain controls interact is described in Section 6.1.1. Also, <inputgain> and <outputgain> settings only apply to conference legs, and they do NOT apply to IVR sessions π
ββοΈ
The <configure_team> element creates and manipulates groups for personalized mixes. You can read more about personalized mixes in Section 5.8 π
The <subscribe> element requests notifications for call leg related events, such as asynchronous DTMF digit reports. Details about call leg events are in Section 7 π
If the default parameters are fine for the leg the client wants to put into the conference, a normal SIP INVITE with no MSCML body is enough. But if the client wants to change one or more parameters, it can include an MSCML body along with the SDP body π
The client can change the conference leg parameters during the conference by sending a SIP INFO on the dialog representing the conference leg. Just remember that the client can't modify SDP in an INFO message, so that's a hard no π
The media server sends a response once it's finished processing the <configure_leg> request. The format of the <configure_leg> response is detailed in Section 10.3.
5.4. Terminating a Conference π
okay so, to remove a leg from the conference, the client sends a SIP BYE on the dialog for that leg π bye bye bestie
if the client wants to end the whole conference for everyone, it sends a SIP BYE on the Conference Control Leg π and if people are still in there when the media server gets that BYE, the media server sends its own SIP BYE requests to all the remaining legs so nobody gets left behind. full cleanup, no cap π§Ήβ¨
the media server sends a 200 OK back to that BYE while it's sending out BYEs to the other legs π«Ά and the reason is kind of iconic: you can't send a provisional response to a non-INVITE request, but tearing down the other legs could take longer than the retransmission timer limits of the original request. so the 200 OK goes out first, periodt π
while the conference is being cleaned up, the media server MUST reject any new INVITEs to the terminated conference with a 486 Busy Here response π« this basically tells the caller that the conference can't take any new members while it's being deleted. closed for business, bestie πΈ
5.5. Conference Manipulation π
once the conference has started, the client can manipulate the whole conference or one specific participant leg by sending commands on the matching SIP dialog. for example, if the client sends MSCML requests on the Conference Control Leg, it can have the media server record the conference, play a prompt to everyone, or ask for reports on active talker events ποΈ it can also mute a participant leg, set up a personalized mix, or ask for reports on call leg events like DTMF keypresses π’ so many options, iykyk
Figure 7 shows an example of an MSCML command that plays a prompt to all conference participants π§
<?xml version="1.0" encoding="utf-8"?>
<MediaServerControl version="1.0">
<request>
<play>
<prompt>
<audio url="http://prompts.example.net/en_US/welcome.au"/>
</prompt>
</play>
</request>
</MediaServerControl>
Figure 7: Full Conference Audio Command - Play
a client can modify a leg by sending an INFO on the dialog for that participant leg π¦ for example, Figure 8 mutes a conference leg π€«
<?xml version="1.0" encoding="utf-8"?>
<MediaServerControl version="1.0">
<request>
<configure_leg mixmode="mute"/>
</request>
</MediaServerControl>
Figure 8: Sample Change Leg Command
in Figure 7 we saw a request to play a prompt to the entire conference π but the client can also play a prompt to just one individual call leg. when it does that, the MSCML request goes inside the SIP dialog of that specific participant π
Section 6 describes the interactive voice response (IVR) services offered by MSCML π if an IVR command arrives on the control channel, it takes effect on the whole conference. this is how you play prompts to everyone, like announcing new participants π£ if an IVR command arrives on an individual leg, it only affects that leg. this is the move for interacting with individual users, like making "waiting rooms", letting someone mute themselves with key presses, or letting a moderator out-dial, etc. main character energy π
A participant leg MUST be configured with mixmode="parked" before any IVR commands with prompt content (the prompturl attribute or a <prompt> element) are sent π parking the leg isolates the participant's input and output media from the conference, so those streams can be used for playing and recording. however, the mixmode doesn't matter if you only want digit collection or recording. <playcollect> and <playrecord> requests without prompt content MAY be sent on participant legs without setting mixmode="parked" β¨
5.6. Video Conferencing π₯
MSCML-controlled advanced conferences, as well as basic conferences controlled by RFC 4240 [2], implicitly support video conferencing through video switching π in video switching, the video stream of the loudest talker (with some hysteresis) is sent to everyone except that talker. the loudest talker gets the video stream from the loudest talker just before them. it's giving fairness π₯°
Media servers MUST ensure that participants receive video media that's compatible with their session π ββοΈ for example, a participant who has set up an H.263 video stream won't receive video from another participant using H.264. Media servers SHOULD implement video transcoding to reduce those media incompatibilities between participants π₯
The media server MUST switch video streams only when it receives a refresh video frame. a refresh frame has all the video info needed to decode that frame, so it doesn't depend on any earlier video frames π§
refresh frames are big and usually sent pretty rarely to save network bandwidth π so the media server MUST implement standard mechanisms to request that the new loudest talker's video encoder sends a refresh frame. that way, the video can switch quickly β‘
5.7. Conference Events π
a client can subscribe to periodic active talker event reports, which show who is included in the conference mix π€ since these are conference-level events, the subscription and the notifications are sent on the Conference Control Leg π«§
Media servers MAY impose limits on the minimum interval for active talker reports for performance reasons. if the client's requested interval is below that imposed minimum, the media server SHOULD set the interval to the minimum value it supports. to avoid pointless notification traffic, the media server SHOULD NOT send a report if the active talker information for the conference hasn't changed during the reporting interval π ββοΈ
Figure 9 is the request for an active talker report, and the report lists the current call legs in the mix π
<?xml version="1.0" encoding="utf-8"?>
<MediaServerControl version="1.0">
<request>
<configure_conference>
<subscribe>
<events>
<activetalkers report="yes" interval="60s"/>
</events>
</subscribe>
</configure_conference>
</request>
</MediaServerControl>
Figure 9: Active Talker Request
event notifications are sent in SIP INFO messages π¨ Figure 10 shows an example of a report.
<?xml version="1.0" encoding="utf-8"?>
<MediaServerControl version="1.0">
<notification>
<conference uniqueid="ab34h76z" numtalkers="47">
<activetalkers>
<talker callid="myhost4sn123"/>
<talker callid="myhost2sn456"/>
<talker callid="myhost12sn78"/>
</activetalkers>
</conference>
</notification>
</MediaServerControl>
Figure 10: Active Talker Event Example
the callid attribute on the <talker> element matches the SIP Call-ID header of the associated dialog π¦ so the client can figure out which participant leg each active talker belongs to. the connection is everything π
5.8. Conferencing with Personalized Mixes π
MSCML lets clients make personalized mixes with the <configure_team> element, for when the standard mixmode settings don't give enough control ποΈ the <configure_team> element is a child of <configure_leg>.
to make personalized mixes, the client has to figure out how the participants are related to each other π«Ά this is done by working with two MSCML objects:
- The list of team members (
<teammate>elements), set using<configure_team> - The mixmode attribute set through
<configure_leg>
the media server uses the values of these objects to decide which audio inputs to combine for output to each participant π§ in a normal conference, each participant hears the conference mix minus their own input, as long as they're part of the mixed output. the team list lets the client name other participants that the leg can hear in addition to the normal mixed output. note that personalized mix settings only apply to audio and don't affect video switching π¬
team relationships are implicitly symmetric πͺ if the client sets participant A as a team member of participant B, the media server automatically sets participant B as a team member of A.
the id attribute set through <configure_leg> is how you identify each participant. a unique ID MUST be assigned to each participant included in a personalized mix π and the IDs used MUST be unique within the scope of the conference they appear in.
on its own, the team list only defines which participants the leg can hear π the mixmode attribute of each team member decides whether their audio input goes into the personalized mix. if the client sets the teammate's mixmode to private, it's part of the mix. if the mixmode is set to anything else, it isn't π
5.8.1. MSCML Elements and Attributes for Personalized Mixes π
personalized mixes rely on two major MSCML elements:
<configure_leg>, using the mixmode attribute settingmixmode="private"<configure_team>
the <configure_team> element lets the user make participants members of a team within a specific conference π§ it's a child of the <configure_leg> parent element.
the client sends the <configure_team> element in a <configure_leg> request, either in a SIP INVITE or a SIP INFO:
- In an INVITE, to join a participant whose properties differ from the properties established for the conference as a whole.
- In an INFO, to change the properties for an existing leg.
the two attributes of the configure_team element are id and action. the id attribute MUST contain the unique ID of the leg being modified, as set in the original <configure_leg> request πͺͺ the action attribute can be add, delete, query, or set, and the default is query. this attribute is how the user changes the team list. Table 1 describes what each action does π
+--------+----------------------------------------------------------+
| Action | Description |
+--------+----------------------------------------------------------+
| add | Adds a teammate to the mix. |
| delete | Deletes a teammate from the mix. |
| query | Returns the teammate list to the requestor. This is the |
| | default value. |
| set | Creates a team list when followed by <teammate id="n"> |
| | and also removes all the teammates from the team list |
| | for example, when the creator (originator) of the team |
| | list on that specific conference leg wants to remove all |
| | of the teammates from the team. If the set operation |
| | removes all teammates from a participant, that |
| | participant hears the full conference mix. |
+--------+----------------------------------------------------------+
Table 1: Configure Team Actions
5.8.2. Example Usage of Personalized Mixes β¨
okay so the big use case for personalized mixing is coaching π one person quietly helps another while a customer is on the line. there are three people in this scenario:
- The Supervisor, who coaches the agent. π§
- The Agent, who talks to the customer. π§
- The Customer, who talks to the agent. π
here's the coached conference setup in Table 2 π
+-------------+------------+------------+---------+-----------------+
| Participant | ID | Team | Mixmode | Hears |
| | | Members | | |
+-------------+------------+------------+---------+-----------------+
| Supervisor | supervisor | Agent | Private | customer + |
| | | | | agent |
| Agent | agent | Supervisor | Full | customer + |
| | | | | supervisor |
| Customer | customer | none | Full | agent |
+-------------+------------+------------+---------+-----------------+
Table 2: Coached Conference Example
to build this, the client does these things:
- The client joins each leg to the conference, being certain to include a unique ID in the
<configure_leg>request. The leg ID needs to be unique only within the scope of the conference to which it belongs. π«Ά - The client configures the teammate list and mixmode of each participant, as required. β¨
steps 1 and 2 can be squished into one MSCML request if you want π the next sections break down each action and its matching MSCML payload.
5.8.2.1. Create the Conference
okay first thing, before anyone joins, the client must create the conference by sending a SIP INVITE with an MSCML <configure_conference> request that has a unique conference identifier. ποΈ
5.8.2.2. Joining and Configuring the Coach
next, join the coach leg and set its vibe by sending a SIP INVITE with a <configure_leg> request. that element gives the leg the unique ID supervisor and sets its mixmode to private π€«
here's the MSCML request:
<?xml version="1.0"?>
<MediaServerControl version="1.0">
<request>
<configure_leg id="supervisor" mixmode="private"/>
</request>
</MediaServerControl>
Figure 11: Join Coach Request
β οΈ the client cannot set up the teammate list for the coach yet, because nobody else is in the conference! you have to join a participant before you can add them as a teammate for someone else. no shortcuts bestie π
5.8.2.3. Joining and Configuring the Agent
now the agent leg joins πββοΈ the <configure_leg> request gives it the unique ID "agent" and adds the supervisor as a team member of the agent. team member relationships are symmetric, so this also adds the agent as a team member for the coach. it's a two-way street, iykyk π¦
here's the MSCML request:
<?xml version="1.0"?>
<MediaServerControl version="1.0">
<request>
<configure_leg id="agent">
<configure_team action="set">
<teammate id="supervisor"/>
</configure_team>
</configure_leg>
</request>
</MediaServerControl>
Figure 12: Join Agent Request
the agent's mixmode is full, which is already the default, so there's no need to set it explicitly. lazy-but-correct energy πΈ
5.8.2.4. Joining and Configuring the Client
last one! the client leg joins and gets configured by sending a SIP INVITE with a <configure_leg> request. the element just sets the unique ID to "customer". the media server doesn't need anything else because full mixmode is the default and the customer has no team members π§
here's the request:
<?xml version="1.0"?>
<MediaServerControl version="1.0">
<request>
<configure_leg id="customer"/>
</request>
</MediaServerControl>
Figure 13: Join Client Request
technically, the customer leg doesn't have to have a unique ID, since it won't be anyone's teammate π€·ββοΈ BUT when you're doing coached conferencing, we RECOMMEND giving every leg a unique ID in the initial INVITE request. that way you don't have to send a SIP INFO later if you decide you want personalized mixing for the customer leg. future-you will thank you π
and just like that, the conference is set up exactly like Table 2 β¨π
6. Interactive Voice Response (IVR) β¨
okay so in the IVR model, the media server acts as a media-processing proxy for the UAC. this is super useful when the UAC is a media gateway or some other device that can't do a lot of media processing on its own π
the usual MSCML setup is an application server acting as the MSCML client. the client can use the SIP Service URI concept (RFC 3087) to kick off a service, then it uses RFC 4240 [2] to start an MSCML session on a media server. here's how it all connects in Figure 14:
SIP +--------------+
Service URI | Application |
/----------------| Server |
/(e.g., RFC 3087) +--------------+
/ | MSCML
/ SIP | Session
/ +--------------+
+-----+/ RTP | |
| UAC |======================| Media Server |
+-----+ | |
+--------------+
Figure 14: IVR Model
the IVR service does the basics: playing announcements, collecting DTMF digits, and recording ποΈ it's all driven by Media Server Control Markup Language (MSCML) directives tucked into the message body of a SIP request. the big IVR requests are <play>, <playcollect>, and <playrecord> π
multifunction media servers MUST use the URI conventions from RFC 4240 [2] π and the service indicator for MSCML IVR MUST be set to "ivr", like this:
sip:ivr@ms.example.net
the VoiceXML IVR service indicator is "dialog". that one MUST NOT be used for any other interactive voice response control mechanism π«
the media server MUST accept MSCML IVR payloads in INFO requests and MUST NOT accept them in the initial or subsequent INVITEs. INFO avoids some timing drama that happens with INVITEs, and it takes less processing on both the client and the media server π§ββοΈ
the media server tells the client the command is done with a <response> message. that has the final status plus any data, like collected DTMF digits π¨
π the media server does not queue IVR requests! if a new IVR request shows up while another one is still going, the media server stops the first one and runs the new one. the media server sends a<response>for the first request and hands back any data it collected up to that point. if a client wants to stop a request without starting a new one, it sends a<stop>request, which also triggers a<response>. no waiting in line here, it's giving main character energy π
the media server treats a SIP re-INVITE that changes the established SDP parameters as an implicit <stop> request. examples of SDP changes like that include receiving hold SDP or removing an audio or video stream. when this happens, the media server immediately ends the running <play>, <playcollect>, or <playrecord> request and sends a <response> saying reason=stopped π
6.1. Specifying Prompt Content
the MSCML IVR requests give you two ways to specify what gets played to the user: the <prompt> element and the prompturl attribute πΆ clients MUST NOT use both methods in a single IVR request. clients SHOULD use the more flexible <prompt> mechanism. the prompturl attribute is deprecated and may not be supported in future MSCML versions, so be careful with it π₯Ί
6.1.1. Use of the Prompt Element β¨
okay so the <prompt> element is totally allowed (it MAY show up) in the body of a <play>, <playcollect>, or <playrecord> request π It's how you tell the caller what to hear. A prompt sequence is basically a playlist made of one or more references to physical content files, spoken variables, or dynamic URLs that hand back a sub-sequence of files or variables. The <prompt> element also comes with a bunch of attributes that control how the included content plays back. bestie, let's go through them π
Attributes of <prompt>:
baseurl- optional, no default value: this one is a total time-saver π¦ Instead of typing the same long address over and over, you set a base URL once, and it gets stuck onto the front of any URL in the sequence that isn't fully qualified. It makes the notation nicer AND shrinks the MSCML payload size.delay- optional, default value0: this is the pause between repetitions of the<prompt>sequence. It does nothing to the first run-through, so the pause only kicks in between loops. It's a time value (see Section 4.2.1) that starts at 0 and goes up from there πΈduration- optional, default valueinfinite: this sets the max amount of time the media server can keep repeating the sequence. It's how the client puts a ceiling on how long the play can go on. The value is a time value (see Section 4.2.1) from1msonwards, OR one of the stringsimmediateandinfinite.Immediatetells the media server to stop playing right now, whileinfinitemeans there's no limit at all πgain- optional, default value0: this sets the absolute gain for the content inside<prompt>, measured in dB. The media server MAY quietly cap any values that go past the gain limits the platform has. Once the content is done playing, the level goes back to what it was before π₯gaindelta- optional, default value0: this one is the relative gain for the content inside<prompt>, also in dB. Same deal: the media server MAY quietly cap values that go over the platform's gain limits, and the level snaps back to its original value when playback finishes πrate- optional, default value0: this sets the absolute playback rate of the content compared to normal. You give it a positive percentage to go faster or a negative percentage to go slower. If you ask for something above the max or below the min, the server quietly sets it to the max or min instead. The rate goes back to its original value once the content inside<prompt>is finished πratedelta- optional, default value0: this one is the playback rate relative to its current rate, again as a positive percentage (faster) or negative percentage (slower). Same rules asrate: anything above the max or below the min gets quietly set to the max or min, and the rate resets to its original value when the content inside<prompt>has completed πlocale- optional, no default value: this tells the server which language and country variant to use when it resolves spoken variables. The language is a two-letter code from ISO 639, and the country variant is a two-letter code from ISO 3166. You stick the two together with a single underscore (%x5F) character β¨offset- optional, default value0: this is a time value (see Section 4.2.1) that says where in the sequence play should begin. The offset only matters for the first repetition, so every repeat after that starts from 0. Allowed values are positive time values from 0 onwards. If there are multiple content files, the offset can land on any point in the sequence. And if the offset is bigger than the sequence's total time, it "wraps" back to the beginning and keeps going until the media server hits that offset π¦repeat- optional, default value1: this controls how many times the media server plays the sequence inside<prompt>. Allowed values are integers from 0 on up, plus the stringinfinite, which means "keep going forever." Sorepeat=2plays the sequence twice, andrepeat=0(which is allowed!) means it doesn't play at all πstoponerror- optional, default valueno: this decides what happens when there's an error fetching remote content. If it's set toyes, play ends the moment a fetch error happens, and the response includes details about the failure. If it's set tono, the media server quietly moves on to the next URL in the sequence when a fetch fails π
Clients MUST NOT include both gain and gaindelta attributes within a single <prompt> element. no exceptions, babe π«
When the client explicitly controls the output gain on a conference leg (see Section 5.3), the gain and gaindelta attributes SHOULD interact with the conference leg output gain settings like this:
- Conference leg output gain set to
<fixed>: thegainandgaindeltaattributes work exactly the same as before. The only difference is that the baseline gain value, before any playback changes get applied, is whatever value was specified for the conference leg πΈ - Conference leg output gain set to
<auto>: when playback gain controls are in use, the automatic gain control settings for that leg get suspended for the whole playback operation. Thegainandgaindeltaattributes still work the same way. Once playback is done, the automatic gain control settings come back on π
Media servers SHOULD support rate controls for content. HOWEVER, media servers MAY quietly ignore rate change requests if the content limitations don't let the request go through. Clients MUST NOT include both rate and ratedelta attributes within a single <prompt> element, so pick one and move on π
Figure 16 shows a sample prompt block. Look how cute it is π
<prompt stoponerror="yes"
baseurl="file:////var/mediaserver/prompts/"
locale="en_US" offset="0" gain="0" rate="0"
delay="0" duration="infinite" repeat="1">
<audio url="num_dialed.raw" encoding="ulaw"/>
<variable type="dig" subtype="ndn" value="3014170700"/>
<audio url="num_invalid.wav"/>
<audio url="please_check.wav"/>
</prompt>
Figure 16: Prompt Block Example
6.1.1.1. <audio> and <variable> Elements
okay so clients build prompt sequences out of two elements: <audio> and <variable> π an <audio> element MAY point at content with audio, video, or both. the name stayed "audio" for backwards compatibility, so no cap, it's a bit of a misnomer π
here's the attribute rundown:
Attributes of <audio>:
url- required, no default value: the URL of the content to fetch and play β¨ it can be a local or remote (NFS)file://URL, or anhttp://orhttps://URL. if the URL isn't fully qualified and abaseurlattribute was set, thebaseurlvalue gets prepended to it to make the target URL.encoding- optional, default valueulaw: the content encoding for file formats that aren't self-describing (like .WAV) π¦ allowed values areulaw,alaw, andmsgsm. this only affectsfile://URLs.gain- optional, default value0: sets the absolute gain applied to the content URL, in dB π the media server MAY silently cap values that go past the platform's gain limits. the level goes back to its original value once playback of the content URL is done.gaindelta- optional, default value0: sets the relative gain applied to the content URL, in dB π same deal: the media server MAY silently cap values past the platform limits, and the level reverts when playback finishes.rate- optional, default value0: sets the absolute playback rate relative to normal, as a positive percentage (faster) or a negative percentage (slower) πββοΈ any value that tries to go above the max or below the min just silently snaps to the max or min. the rate reverts once playback of the content URL is complete.ratedelta- optional, default value0: sets the playback rate relative to its current rate, as a positive percentage (faster) or a negative one (slower) π’ same snapping rules: above the max or below the min silently becomes the max or min, and the rate reverts when playback finishes.
Clients MUST NOT include both gain and gaindelta attributes within a single <audio> element. π
ββοΈ
When the client explicitly controls the output gain on a conference leg, as described in Section 5.3, the gain and gaindelta attributes SHOULD interact with the conference leg output gain settings in the following manner. the vibes go like this:
- Conference leg output gain set to
<fixed>: the operation ofgainandgaindeltais unchanged. however, the baseline gain value before any playback changes are applied is the value specified for the conference leg. π― - Conference leg output gain set to
<auto>: when playback gain controls are used, the automatic gain control settings for the leg are suspended for the duration of the playback operation.gainandgaindeltastill work the same way. the automatic gain control settings get reinstated once playback has finished πΈ
Media servers SHOULD support rate controls for content. however, media servers MAY silently ignore rate change requests if content limitations don't allow the request to be honored π and clients MUST NOT include both rate and ratedelta attributes within a single <audio> element.
Media servers MUST support local and remote (NFS) file:// scheme URLs and http:// and https:// scheme URLs for content retrieval. no exceptions, periodt π
NOTE: The provisioning of NFS mount points and their mapping to the file:// scheme is purely a local matter at the media server.
MSCML also supports http:// and https:// scheme URLs that return a list of physical URLs using the text/uri-list MIME type π§ this is so iconic because apps can dynamically generate prompt sequences at execution time, and that job stays separate from both the client and the media server.
Spoken variables are specified using the <variable> element, which has the attributes below. MSCML's spoken variables are based on those described in Audio Server Protocol [17] ποΈ
Attributes of <variable>:
type- required, no default value: the major type format of the spoken variable to be played π allowed values are"dat"(date),"dig"(digit),"dur"(duration),"mth"(month),"mny"(money),"num"(number),"sil"(silence),"str"(string),"tme"(time), and"wkd"(weekday).subtype- optional, no default value: the minor type format of the spoken variable. allowed values depend on thetypevalue. the possible ones are"mdy","ymd", and"dmy"for dates,"t12"and"t24"for times,"gen","ndn","crd", and"ord"for digits, and"USD"for money.value- required, no default value: a string that gets interpreted using thetypeandsubtypeformatting info plus thelocaleattribute of the parent<prompt>element, so the spoken variable renders correctly π«Ά
If the locale attribute wasn't specified in <prompt>, the media server SHOULD make a selection based on platform configuration. if the precise locale requested can't be honored, the media server SHOULD select the closest match based on the available content.
IVR apps usually need specialized prompt content that the app provider authors. for a quality user experience, those specialized prompts and the spoken variables must come from the same speaker π€ but the media server supports multiple apps at the same time, so provisioning every app's prompts and matching spoken variables locally is extremely difficult. so we STRONGLY RECOMMEND that clients use the dynamic URL mechanism described earlier to generate spoken variables from an external web server that returns text/uri-list content. π«
6.2. Multimedia Processing for IVR
okay this section is about the multimedia side of things π¬
MSCML IVR requests implicitly support multimedia content. the multimedia capabilities are controlled by the audio and video media negotiated for the dialog, plus the content the client specifies for play and record operations. if the content for delivery has both audio and video tracks and the dialog has audio and video streams, both tracks get streamed to the caller πΌ likewise, if the dialog has both audio and video streams and the content format supports both (e.g., .3gp files), the media server records both streams to the file.
If there is a mismatch between the real time media and the specified content, the media server MUST play or record the appropriate content tracks rather than failing the request π ββοΈ for example, if the client requested playback of content with audio and video tracks but only audio media is established for the dialog, the media server should play the audio track. if the dialog has both audio and video media but the content is audio-only, the media server MAY stream a pre-provisioned video track to the caller. Media servers SHOULD implement video transcoding functions to minimize incompatibilities between real time media and content π
The media server MUST begin recording video media only when it receives a refresh video frame. a refresh frame has all the video info needed to decode that frame, so there's no dependency on data from previous frames πΌοΈ refresh frames are big and generally sent infrequently to save network bandwidth. the media server MUST implement standard mechanisms to request that the caller (video encoder) send a refresh frame, so video recording starts quickly β‘ and the media server MUST begin recording the audio track immediately while it waits for that video refresh frame.
6.3. Playing Announcements <play>
the client issues a <play> request to play an announcement without interruption and with no digit collection π£ one use, for example, is announcing the name of a new participant to the entire conference. the <play> request has the attributes below.
Attributes of <play>:
id- optional, no default value: a client-defined ID for matching requests and responses πoffset- optional, default value0: the time from the beginning of the URL in theprompturlattribute where play begins β±οΈ it's expressed as a time value (Section 4.2.1) from 0 onwards. if the offset is greater than the total time of the content, it "wraps" back to the beginning and keeps going from there until the media server reaches the specified offset.
NOTE: Use of this attribute is deprecated.
promptencoding- optional, no default value: the content encoding for file formats that aren't self-describing (e.g., .WAV). allowed values areulaw,alaw, andmsgsm. this only affectsfile://URLs.
NOTE: Use of this attribute is deprecated.
prompturl- optional, no default value: the URL of the content to be retrieved and played. it can be a local or remote (NFS)file://URL, or anhttp://orhttps://URL.
NOTE: Use of this attribute is deprecated.
The <play> request has one child element defined, <prompt>. Use of <prompt> is described in Section 6.1.1.
The client MUST NOT use both the <prompt> element and the prompturl attribute in a single request. as we discussed earlier, prompturl is only supported for backwards compatibility with older MSCML apps, and its use is deprecated π₯² the more flexible <prompt> element SHOULD be used instead, bestie π
The following play request (Figure 17) example shows the delivery of a complex prompt sequence made of content accessed via NFS plus spoken variables π§©
<?xml version="1.0"?>
<MediaServerControl version="1.0">
<request>
<play id="332985001">
<prompt stoponerror="yes"
baseurl="file:////var/mediaserver/prompts/"
locale="en_US" offset="0" gain="0" rate="0"
delay="0" duration="infinite" repeat="1">
<audio url="num_dialed.raw" encoding="ulaw"/>
<variable type="dig" subtype="ndn" value="3014170700"/>
<audio url="num_invalid.wav"/>
<audio url="please_check.wav"/>
</prompt>
</play>
</request>
</MediaServerControl>
Figure 17: <Play> Request Example π
When the announcement has finished playing, the media server sends a <response> payload to the client in a SIP INFO message π¨ details about the format of <play> responses are in Section 10.4.
6.4. Prompt and Collect <playcollect> π
okay so bestie, the client sends a <playcollect> request to play an announcement (totally optional!) and collect digits π. It runs in two phases, prompt and collect. If the client includes prompt content, either with the <prompt> element or the prompturl attribute, the media server plays it first, and then the collect phase starts. If there's no prompt content, collect starts right away β‘.
The basic attributes of <playcollect> are the same as the ones for <play> from Section 6.3 π
. On top of those, <playcollect> has extra ones for digit buffering and barge-in, collection timers, special DTMF key functions, and logging of user DTMF input. Each category and its attributes are covered below β¨.
6.4.1. Control of Digit Buffering and Barge-In π§
this part is so cute, ngl π₯Ή. Whenever the media server is handling a call that specifies an MSCML service (that's "conf" and "ivr"), it's constantly listening for DTMF digits and tucking them into a quarantine buffer π«. When a <playcollect> request arrives, that buffer gets checked. The media server compares any digits already buffered for barge-in, and looks for matches with DTMF grammars or special purpose keys π. This is what gives you type-ahead behavior for menu traversal and other IVR stuff, which is honestly iconic π.
Attributes for Control of Digit Buffering and Barge-In:
cleardigits- optional, default value "no": Specifies whether previous user input should be considered or ignored for barge-in purposes and DTMF matching. When it is set to "yes", any previously buffered digits are removed, so prior user input is ignored. If it is set to "no", previously buffered digits will be considered. If "cleardigits" is set to "no" and barge-in is enabled, previously buffered digits will immediately terminate the prompt phase. In this case, the prompt is not played, and digit collection begins immediately π.barge- optional, default value "yes": Specifies whether user input will barge the prompt and force transition to the collect phase. When it is set to "yes", a DTMF input will barge the prompt. When it is set to "no", the prompt phase cannot be barged, and any user input during the prompt is placed in the quarantine buffer for inspection during the collect phase. Note that if the "barge" attribute is set to "no", the "cleardigits" attribute implicitly has a value of "yes". This ensures that the media server does not leave DTMF input that occurred prior to the current collection in the quarantine buffer after the request is completed π§Ή.
6.4.2. Mapping DTMF Keys to Special Functions π
the client can define mappings between DTMF digits and special functions, and the media server runs the special function whenever the matching digit gets detected π. MSCML has two attributes that set up mappings affecting how the collect phase ends. They're listed below π.
DTMF Key Mappings for <playcollect>:
escapekey- optional, default value "*": Specifies a DTMF key that indicates that the user wishes to terminate the current operation without saving any input collected to that point. Detection of the mapped DTMF key terminates the request immediately and generates a response π.returnkey- optional, default value "#": Specifies a DTMF key that indicates that the user has completed input and wants to return all collected digits to the client. When the media server detects the returnkey, it immediately terminates collection and returns the collected digits to the client in the<response>message π.
MSCML defines three more mappings for video cassette recorder (VCR) style controls while a prompt sequence is playing πΌπ. Media servers SHOULD support VCR controls. However, if the media server does not support VCR controls, it MUST silently ignore DTMF inputs mapped to VCR functions and complete the <playcollect> request. The VCR control attributes are below π.
Attributes for VCR Controls:
skipinterval- optional, default value "6s": The "skipinterval" attribute indicates how far the media server should skip backwards or forwards when the rewind key (rwkey) or fast forward key (ffkey) is pressed, specified as a time value (Section 4.2.1) β©.ffkey- optional, no default value: The "ffkey" attribute maps a DTMF key to a fast forward operation equal to the value of the "skipinterval" attribute.rwkey- optional, no default value: The "rwkey" attribute maps a DTMF key to a rewind action equal to the value of the "skipinterval" attribute βͺ.
Clients MUST NOT map the same DTMF digit to both the "rwkey" and "ffkey" attributes in a single <playcollect> request. π« no double-mapping, bestie!
VCR control operations are bounded by the beginning and end of the prompt sequence. A rewind action that moves the offset before the beginning of the sequence results in playback starting at the beginning of the sequence (i.e., offset=0). A fast forward action that moves the offset past the end of the sequence results in the media server's treating the sequence as complete π¬.
6.4.3. Collection Timers β°
MSCML defines several timer attributes that control how long the media server waits for digits in the input sequence. All timer settings are time values (Section 4.2.1). The list below describes these attributes and what they do π.
Collection Timer Attributes:
firstdigittimer- optional, default value "5000ms": Specifies how long the media server waits for the initial DTMF input before terminating the collection. Expressed as a time value (Section 4.2.1) from 1ms onwards or the strings "immediate" and "infinite." The value "immediate" indicates that the timer should fire immediately whereas "infinite" indicates that the timer will never fire π°οΈ.interdigittimer- optional, default value "2000ms": Specifies how long the media server waits between DTMF inputs. Expressed as a time value (Section 4.2.1) from 1ms onwards or the strings "immediate" and "infinite." The value "immediate" indicates that the timer should fire immediately, whereas "infinite" indicates that the timer will never fire π«.extradigittimer- optional, default value "1000ms": Specifies how long the media server waits for additional user input after the specified number of digits has been collected. Expressed as a time value (Section 4.2.1) from 1ms onwards or the strings "immediate" and "infinite." The value "immediate" indicates that the timer should fire immediately, whereas "infinite" indicates that the timer will never fire πΈ.interdigitcriticaltimer- optional, defaults to the value of the interdigittimer attribute: Specifies how long the media server waits after a grammar has been matched for a subsequent digit that may cause a longer match. Expressed as a time value (Section 4.2.1) from 1ms onwards or the strings "immediate" and "infinite." The value "immediate" results in "shortest match first" behavior, whereas "infinite" means to wait indefinitely for additional input. If not explicitly specified otherwise, this attribute is set to the value of the 'interdigittimer' attribute π§ .
The extradigittimer setting is what lets the "returnkey" input get associated with the current collection. For example, if maxdigits is set to 3 and returnkey is set to #, the user may enter either "x#", "xx#", or "xxx#", where x represents a DTMF digit π’.
If the media server detects the "returnkey" pattern during the "extradigit" interval, it returns the collected digits to the client and removes the "returnkey" from the digit buffer π§½.
If this were not the case, the example would return "xxx" to the client and leave the terminating "#" in the digit buffer. At the next <playcollect> request, the media server would process the '#'. This might result in the termination of the following prompt, which is clearly not what the user intended π.
The extradigittimer has no effect unless returnkey has been set π ββοΈ.
6.4.4. Logging Caller DTMF Input π
ok, this one is serious, bestie π₯Ί. Standard SIP mechanisms, such as the ones discussed in Security Considerations (Section 14), protect MSCML protocol exchanges and the information they contain. Those protections do not apply to data captured in media server log files. In general, media server logging is platform specific and therefore is not covered by this specification π₯οΈ. However, one part of logging matters a lot: capturing sensitive information, like personal identification numbers or credit card numbers π³. The media server has no way to tell whether the DTMF input it receives is sensitive, because that's up to the client. So MSCML includes a per-request mechanism that clients can turn on as needed to stop captured DTMF from being logged π.
The "maskdigits" attribute controls whether detected DTMF digits appear in the log output. Clients use this attribute when the media server collects sensitive information that should not be accessible through the log files π«£.
Maskdigits Attribute:
maskdigits- optional, default value "no": Controls whether user DTMF inputs are captured in media server log files. The possible values for this attribute are "yes" and "no" π«Ά.
6.4.5. Specifying DTMF Grammars π₯
okay so MSCML has four ways to specify DTMF grammars π§: the maxdigits attribute (the simple one that just collects any number of digits up to a max), regular expressions, MGCP [5] digit maps, and H.248.1 [6] digit maps. A media server MUST support the maxdigits and regular expression methods for specifying DTMF grammars and SHOULD support MGCP and H.248.1 methods. A client MUST NOT mix DTMF grammar types in a single <playcollect> request π
here's the lowdown on the maxdigits attribute π
Maxdigits Attribute:
maxdigits- optional, no default value: Specifies the maximum number of DTMF digits to be collected.
the <pattern> element is where you tell the media server what digit patterns to look for π it can hold three different child elements, and each one tells the server what kind of DTMF grammar you're using. the <pattern> element has no attributes, so it's giving minimal π¦
<regex>- Use regular expressions to define DTMF patterns to match. The complete regular expression syntax used in MSCML is described in Appendix A.<mgcpdigitmap>- Use digit maps as specified in MGCP [5].<megacodigitmap>- Use digit maps as specified in H.248.1 [6].
ok the rules for these are super specific π when you're using regex grammars, at least one <regex> element MUST be present in <pattern>. you MAY have multiple <regex> elements, which is iconic β¨ but if you go with <mgcpdigitmap> or <megacodigitmap>, then <pattern> MUST contain only one grammar element. no drama, just rules π
the DTMF grammar elements <regex>, <mgcpdigitmap>, and <megacodigitmap> all have the attributes below πΈ
Attributes of DTMF Grammar Elements:
value- required, no default value: Specifies a string representing a DTMF grammar matching the parent element type (e.g., regex). Regex values represent a single DTMF grammar. MGCP and MEGACO digit maps allow multiple grammars to be described in a single string.name- optional, no default value: Associates a client defined name for the grammar that is sent back in the<playcollect>response. This attribute is most useful with regex type grammars as each grammar element can have a unique name.
6.4.6. Playcollect Response π
when the <playcollect> is finished, the media server sends a <response> payload back to the client in a SIP INFO message. so cute, the answer comes right back to you π
details of the <playcollect> response are in Section 10.5, go check that out π§
6.4.7. Playcollect Example π
okay so this <playcollect> request (Figure 18) shows how the maxdigits attribute controls digit collection. look at how clean it is π
<?xml version="1.0"?>
<MediaServerControl version="1.0">
<request>
<playcollect id="332986004" maxdigits="6" firstdigittimer="10000"
interdigittimer="5000" extradigittimer="1000"
interdigitcriticaltimer="1000" returnkey="#" escapekey="*"
cleardigits="no" barge="yes" maskdigits="no">
<prompt baseurl="http://www.example.com/prompts/">
<audio url="generic/en_US/enter_pin.wav"/>
</prompt>
</playcollect>
</request>
</MediaServerControl>
Figure 18: <Playcollect> Request Example Using the Maxdigits Attribute π
6.5. Prompt and Record <playrecord> ποΈ
the <playrecord> request tells the media server to convert and maybe transcode the RTP payloads it gets, then store them at the specified URL using the requested content codec(s) and file format. it's a two-phase glow-up: prompt, then record π
the <playrecord> request shares the basic attributes of <play> and <playcollect>, which you can read about in Section 6.3 β¨ MSCML also adds more attributes that control how the prompt and recording phases behave. those phases and their attributes are explained in the text and tables below π
6.5.1. Prompt Phase π¦
whether a prompt plays before recording starts depends on the prompturl attribute or the child <prompt> element. heads up, the prompturl attribute is deprecated, so clients SHOULD use <prompt> instead π
ββοΈ
when the client wants the media server to prompt the caller before recording, <playrecord> has two stages. the first one works like a <playcollect> operation. the client can make the prompt phase interruptible by DTMF input (barge) and can set an escape key that ends the <playrecord> request before the recording phase even starts π
these are the <playrecord> attributes that control the prompt phase π
barge- optional, default value "yes": Specifies whether user input will barge the prompt and force transition to the record phase. When it is set to "yes", a DTMF input will barge the prompt. When it is set to "no", the prompt phase cannot be barged, and any user input during the prompt is placed in the quarantine buffer for inspection during the collect phase. Note that if the "barge" attribute is set to "no", the "cleardigits" attribute implicitly has a value of "yes". This ensures that the media server does not leave DTMF input that occurred prior to the current collection in the quarantine buffer after the request completes.cleardigits- optional, default value "no": Specifies whether previous user input should be considered or ignored for barge-in purposes. When it is set to "yes", any previously buffered digits are removed, so prior user input is ignored. If it is set to "no", previously buffered digits will be considered. If "cleardigits" is set to "no" and barge-in is enabled, previously buffered digits will terminate the prompt phase immediately. In this case, the prompt is not played, and recording begins immediately.escapekey- optional, default value "*": Specifies a DTMF key that indicates the user wishes to terminate the current operation without saving any input recorded to that point. Detection of the mapped DTMF key terminates the request immediately and generates a response.
so if the escape key gets detected, that generates a response message and the whole operation returns right away π if the user presses any other key and the prompt is interruptible (barge="yes"), the play stops immediately and the recording phase begins π₯
6.5.2. Record Phase π€
if the request moves on to the recording phase, the media server tosses any digits from the collect phase out of the quarantine buffer ποΈ this stops unintended termination of the recording. the attributes below control how recording behaves π
these are the <playrecord> attributes for the record phase π
recurl- required, no default value: Specifies the target URL for the recorded content.recencoding- optional, default value "ulaw": Specifies the encoding of the recorded content if it cannot be inferred from the recurl. Possible values are "ulaw", "alaw", and "msgsm."mode- optional, default value "overwrite": Specifies whether the recording should overwrite or be appended to the target URL. Allowable values are "overwrite" and "append."duration- optional, default value "infinite": Specifies the maximum allowable duration for the recording. Expressed as a time value (Section 4.2.1) from 1 onwards or the strings "immediate" and "infinite." The value "immediate" indicates that recording will end immediately, whereas "infinite" indicates recording should continue indefinitely. If the maximum duration is reached, the<playrecord>request will terminate and generate a response.beep- optional, default value "yes": Specifies whether a beep should be played to the caller immediately prior to the start of the recording phase. Allowable values are "yes" and "no."initsilence- optional, default value "3000ms": Specifies how long to wait for initial speech input before terminating (canceling) the recording. Expressed as a time value (Section 4.2.1) from 1ms onwards or the strings "immediate" and "infinite." The value "immediate" indicates that the timer should fire immediately, whereas "infinite" directs the media server to wait indefinitely.endsilence- optional, default value "4000ms": Specifies how long the media server waits after speech has ended to stop the recording. Expressed as a time value (Section 4.2.1) from 1ms onwards or the strings "immediate" and "infinite." When set to "infinite", the recording will continue indefinitely after speech has ended and will only terminate due to a DTMF keypress or because the input has reached the maximum desired duration.recstopmask- optional, default value "0123456789ABCD#*": Specifies a list of individual DTMF characters that, if detected, will cause the recording to be terminated. To ensure that the input of a specific key does not cause the recording to stop, remove the DTMF key from the list.
media servers MUST support local and remote (NFS) "file://" scheme URLs in the "recurl" attribute π and MSCML supports "http://" and "https://" scheme URLs indirectly through the <managecontent> (Section 8) request π
the media server buffers any digits collected in the prompt phase and returns them in the response, except for the ones listed in "recstopmask" π§Ί
the media server checks any digits detected during the recording phase against the digits in "recstopmask" to figure out whether they mean "stop recording" π digits that aren't in the recstopmask get ignored and passed into the recording π§ if DTMF input ends the recording, the media server sends the collected digit back to the client in the <response> π
once recording has started, the media server writes the received media to the specified recurl URL no matter what DTMF events it detects π it's on the client to look at the DTMF input returned in the <response> message and decide whether to keep the audio file, delete it, or maybe re-record π
if the endsilence timer expires, the media server trims the end of the recorded audio by an amount equal to the value of the "endsilence" attribute βοΈ
when the recording is finished, the media server generates a <response> message and sends it to the client in a SIP INFO message. details of the <playrecord> response are in Section 10.6 π§
6.5.3. Playrecord Example π
this recording example (Figure 19) plays a prompt and records it to the destination in the "recurl" attribute, encoded as MS-GSM in wave format π
<?xml version="1.0"?>
<MediaServerControl version="1.0">
<request>
<playrecord id="5556123"
recurl="file:////nfs.example.com/rec/name.wav"
recencoding="msgsm"
initsilence="5000" endsilence="3000" duration="30000"
barge="yes"
beep="yes"
mode="overwrite"
cleardigits="no"
escapekey="*"
recstopmask="0123456789#*">
<prompt>
<audio url="http://www.example.com/prompts/recordname.wav"/>
</prompt>
</playrecord>
</request>
</MediaServerControl>
Figure 19: Recording Example π¦
6.6. Stop Request <stop> βπ
okay so, <stop> is the client's way of saying "cancel the thing that's happening right now" π It is NOT for starting something new. The media server answers with a <response> message π
The only attribute is id, and it's optional π
The client-defined request id is how the async response finds its way back to the original request. The media server echoes it in its response, so the client knows exactly which request got stopped β¨
Here's an example <stop> request in an MSCML payload (Figure 20) π§
<?xml version="1.0"?>
<MediaServerControl version="1.0">
<request>
<stop id="4578903"/>
</request>
</MediaServerControl>
Figure 20: Stop Example
For what a response to a <stop> request looks like, check out Section 10.2 π
ok and this part is lowkey important π The media server treats a SIP re-INVITE that changes the established SDP parameters as an implicit <stop> request π«£ Examples of that include receiving hold SDP or removing an audio or video stream. When it happens, the media server immediately ends the running <play>, <playcollect>, or <playrecord> request and sends a <response> with reason=stopped π
Heads up bestie: you don't need to send a <stop> yourself for this one. The re-INVITE already does the job π
7. Call Leg Events ππ¦
MSCML has event notifications that are scoped to one specific SIP dialog, aka one call leg π These let the client know about individual DTMF keypresses and various call progress signals, as they happen β¨ The subscription, the event detection, and the notifications for call leg events all live in the same SIP dialog. This is different from the conference level active talker events we covered earlier π For those, the subscription and notifications happen on the conference control leg, but the detection itself happens on one or more participant legs πΈ
Subscriptions for call leg events are made by sending an MSCML <configure_leg> request on the SIP dialog you want π Call leg events can be used with the MSCML conferencing or IVR services. When you're using the IVR service, the <configure_leg> request SHOULD NOT include any conference-related attributes. If they show up anyway, the media server MUST ignore them π Call leg event subscriptions MUST NOT be made on the conference control leg, because that leg has no actual RTP media to process for event detection π The media server MUST reject a <configure_leg> request sent on the conference control leg. No exceptions, periodt π
The <configure_leg> request has the child elements <subscribe> and <events> π«Ά The <events> element can contain two child elements that control call leg event subscriptions: <keypress> and <signal>. A <configure_leg> request MUST contain at most one <keypress> element, but it MAY contain multiple <signal> elements to ask for notifications about different call progress events β¨
7.1. Keypress Events πΉ
7.1. Keypress Events πΉ
Keypress events are for when the client wants to hear about individual DTMF events that aren't tied to a specific <playcollect> request π One use is watching conference legs for DTMF input that needs an app to step in. For example, the moderator can get pinged when a caller wants to speak π€ Keypress events are also useful when the application wants full control over grammars and timing constraints π
When you're subscribing, the <keypress> element has two attributes, report and maskdigits. They're broken down in the list below π§
Keypress Subscription Attributes:
- report - required, no default value: The possible values are
'standard','long','both', and'none'.'standard'means detected digits should be reported π’'long'means long digits should be reported. A long digit is either a single keypress held down for more than one second, or two distinct keypresses (a "double") of the same digit that happen within two seconds of each other, with no other digits in between π«'both'means both'standard'and'long'digit events get reported. A long digit is made up of one or more "normal" digits, so a single long keypress generates one standard event and one'long'event. A "double" produces two standard events and one'long'event π€―'none'means no keypress events get reported. It also turns off keypress event reporting if it was on π ββοΈ
- maskdigits - optional, default value "no": Controls whether user DTMF inputs are captured in media server log files. The possible values are "yes" and "no" π
The media server sends an MSCML response to the subscription right away, as soon as it gets the request. After that, notifications go out to the client whenever the specified events are detected π
When it's a notification, the <keypress> element has a few attributes that describe the event it caught. It also has a child element, <status>, which tells you about any MSCML request that was running when the event happened π§ Here are the notification attributes:
Keypress Notification Attributes:
- digit - required, no default value: The DTMF digit detected. Possible values are
[0-9],[A-D],'#', or'*'π’ - length - required, no default value: The duration class of the DTMF input. Possible values are
'standard'or'long'β±οΈ - method - required, no default value: The keypress detection method that made the notification. Possible values are
'standard','long', and'double'πͺ - interdigittime - required, no default value: The elapsed time between the current event detection and the previous one, written as a time value (see Section 4.2.1) β³
7.1.1. Keypress Subscription Examples π
Here are some MSCML payloads showing a subscription for standard keypress events and then turning keypress reporting off π
Figure 21 is a subscription for standard keypress events π§
<?xml version="1.0"?>
<MediaServerControl version="1.0">
<request>
<configure_leg>
<subscribe>
<events>
<keypress report="standard"/>
</events>
</subscribe>
</configure_leg>
</request>
</MediaServerControl>
Figure 21: Standard Digit Events Subscription
Figure 22 is a client disabling keypress event notifications π ββοΈ
<?xml version="1.0"?>
<MediaServerControl version="1.0">
<request>
<configure_leg>
<subscribe>
<events>
<keypress report="none"/>
</events>
</subscribe>
</configure_leg>
</request>
</MediaServerControl>
Figure 22: Disabling Keypress Event Reporting
7.1.2. Keypress Notification Examples π
These MSCML payloads show keypress event notifications caused by different kinds of DTMF input π¦
Figure 23 is a notification for a standard "4" DTMF digit. In this one it's the first digit detected, so the interdigittime attribute is '0' π
<?xml version="1.0"?>
<MediaServerControl version="1.0">
<notification>
<keypress digit="4" length="standard" method="standard"
interdigittime="0">
<status command="play" duration="10"/>
</keypress>
</notification>
</MediaServerControl>
Figure 23: Standard Keypress Notification
Figure 24 is a notification for a long pound (#) π
<?xml version="1.0"?>
<MediaServerControl version="1.0">
<notification>
<keypress digit="#" length="long" method="long"
interdigittime="200">
<status command="idle" duration="4"/>
</keypress>
</notification>
</MediaServerControl>
Figure 24: Long Keypress Notification
7.2. Signal Events π¨
MSCML can tell you about certain call progress tones through the <signal> element π£ When you're subscribing, <signal> has two attributes, type and report, and no child elements. Here's the breakdown π
Signal Subscription Attributes:
- report - required, no default value: Controls whether the specified signal gets reported. Possible values are
'yes'and'no'. When it's'yes', the media server runs the required signal detection code and reports the events it detects. When it's'no', the media server turns off the matching signal detection code and reports nothing π ββοΈ - type - required, no default value: The type of call progress signal to detect. Possible values are
'busy','ring','CED','CNG', and'400', which correspond to busy tone, ring tone, fax CED, fax CNG, and 400 Hz tone, respectively πΆ
NOTE: The details of media server provisioning needed to support country-specific variants of 'busy' and 'ring' are not covered by this specification π
As mentioned earlier, a single <configure_leg> request MAY contain multiple <signal> elements to ask for notifications about different call progress tones π«Ά A single <configure_leg> request SHOULD NOT contain multiple <signal> elements with the same 'type' attribute value. If the media server gets one like that, it SHOULD honor the last element for that type that shows up in the request π€·ββοΈ
The media server sends an immediate response to the <configure_leg> subscription request, and then sends notifications when the specified signals are detected. One notification goes out as soon as the signal has been reliably detected. If the signal keeps going continuously, no more notifications get sent. If the signal gets interrupted and then comes back, additional notifications WILL be sent π
Hmm, I need to be precise: that last sentence in the original says "will be sent", so I keep it lowercase.
Signal notifications have one attribute, "type", described below π¬
Signal Notification Attribute:
- type - required, no default value: The type of call progress signal that was detected. Possible values are
'busy','ring','CED','CNG', and'400', which correspond to busy tone, ring tone, fax CED, fax CNG, and 400 Hz tone, respectively π
7.2.1. Signal Event Examples πΈ
The MSCML payloads below show a signal event subscription (Figure 25) and a notification (Figure 26) π§
<?xml version="1.0"?>
<MediaServerControl version="1.0">
<request>
<configure_leg>
<subscribe>
<events>
<signal type="busy" report="yes"/>
</events>
</subscribe>
</configure_leg>
</request>
</MediaServerControl>
Figure 25: Signal Event Subscription
<?xml version="1.0"?>
<MediaServerControl version="1.0">
<notification>
<signal type="busy"/>
</notification>
</MediaServerControl>
Figure 26: Signal Event Notification
8. Managing Content <managecontent> π¦β¨
Okay bestie, so MSCML uses the <managecontent> request to move recorded content from the media server to remote locations over HTTP π. It's a store-and-forward model, which means the recording has to finish locally first, and only then can the media server send it on to the web server. This is super useful for things like voice messaging π±, where the caller gets to listen back to their message before it's committed to persistent storage. Iconic. π
The <managecontent> request has no child elements, just the attributes below. π
Managecontent Attributes:
src- required, no default value: Specifies the local source URL of the content. The URL scheme MUST befile://. πdest- required (see note), no default value: Specifies the destination URL. The URL scheme MUST behttp://. Note: If the selected action isdelete, this attribute is optional; otherwise it is required. π―action- optional, default valuemove: Specifies the operation for the media server to execute. Values can be eithermoveordelete. Thedeleteaction operates on the local source file. After a successful move or delete, the media server deletes the source file from its local storage. If the request is unsuccessful, the source file is not deleted, which gives the client complete control of the retry strategy. πhttpmethod- optional, default valuepost: HTTP protocol method for the media server to use in the HTTP request. The only values arepostorput. πΈname- required (see note), no default value: Specifies the field name for the content in the form when using thepostmethod. This is not to be confused with thesrcordestattributes. Note: This attribute is required when thehtttpmethodhas the valuepostand is optional otherwise. π·οΈfetchtimeout- optional, default value10000ms: Specifies the maximum time allowed for the transfer to complete. Expressed as a time value (Section 4.2.1) from1msonwards. β°mimetype- required (see note), no default value: Specifies the MIME type that the media server will use for the content transfer. If it is not provided, the media server MUST try to infer it from the content file extension based on a platform specific mapping table. A non-normative, example mapping table is shown in Table 3. To avoid ambiguity, we RECOMMEND that clients explicitly set this attribute. Note: If the MIME type of the content cannot be inferred from the file extension, this attribute is required. π§
Table 3 shows common audio and video MIME types and possible file extension mappings. π¬
+-----------+--------------------+
| Extension | MIME Type |
+-----------+--------------------+
| alaw | audio/x-alaw-basic |
| ulaw | audio/basic |
| msgsm | audio/ms-gsm |
| wav | audio/x-wav |
| tif | image/tiff |
| tiff | image/tiff |
| mov | video/quicktime |
| qt | video/quicktime |
| 3gp | video/3gpp |
| 3gpp | video/3gpp |
+-----------+--------------------+
Table 3: Example File Extension to MIME Type Mappings
Managecontent is purely a transport operation, so the underlying content is not changed by it. Therefore clients MUST ensure that the source and destination file name extensions and MIME types are the same. Failure to do so could result in content that is unreadable. π
β οΈ The ability to move or delete any local file presents a potential risk to the security of the media server system. For this reason, we STRONGLY RECOMMEND that implementers limit local file system access when using <managecontent>. For example, we encourage limiting access as based on file ownership and/or specific directories. ππ
8.1. Managecontent Example π
The following is an example (Figure 27) showing a local file on the media server being transferred to an HTTP URL using the put method. The client sends the following request. π¨
<?xml version="1.0"?>
<MediaServerControl version="1.0">
<request>
<managecontent id="102"
src="file:////var/mediaserver/rec/6A5GH49B.ulaw"
dest="http://www.example.com/recordings/myrecording.ulaw"
mimetype="audio/basic" action="move" httpmethod="put"
fetchtimeout="5000"/>
</request>
</MediaServerControl>
Figure 27: Managecontent Example
Note that the client can change the temporary file name assigned by the media server as part of this operation, as shown. β¨
If the request is ambiguous, the media server MUST return a status code of 400 and text Bad Request. If the media server is unable to execute a syntactically correct and unambiguous request, it MUST return a 500 status code with the text Server Error. For example, the local file system access restrictions may prevent deletion of the specified file. In this case, the reason attribute in the response conveys additional details on the server error that occurred. If there is a network or remote server error, the media server provides detailed error information in the <error_info> element contained in the media server response. Additional information regarding <managecontent> responses is provided in Section 10.7. π¨
9. Fax Processing π π©·
9.1. Recording a Fax <faxrecord> π¨οΈ
The <faxrecord> request directs the media server to process a fax in answer mode. The reason it's a separate request from <playrecord> is that the media server needs to know to process the T.30 [18] or T.38 [19] fax protocols. π§
The <faxrecord> request has multiple attributes and one child element, <prompt>. Its attributes are described in the list below. π
Attributes of <faxrecord>:
lclid- optional, default value""(the empty string): A string that identifies the called station. πprompturl- optional, no default value: The URL of the fax content to be retrieved and played. The target may be a local or remote (NFS)file://scheme URL or anhttp://orhttps://scheme URL. NOTE: Use of this attribute is deprecated. π ββοΈpromptencoding- optional, no default value: Specifies the content encoding for files that do not have atifortiffextension. The only allowable value istiff. This attribute only affectsfile://scheme URLs. NOTE: Use of this attribute is deprecated. π ββοΈrecurl- optional, no default value: Specifies the target URL for the recorded content. π―rmtid- optional, no default value: Specifies the calling station identifier of the remote terminal. If present, the media server MUST reject transactions with the remote terminal if the remote terminal's identifier does not match the value ofrmtid. π«
Clients SHOULD use the more flexible <prompt> mechanism for specifying fax content. Use of the prompturl attribute is deprecated and may not be supported in future MSCML versions. The <prompt> element is described in Section 6.1.1. A <prompt> element sent in a <faxrecord> request MUST NOT contain <variable> elements. π«Ά
Media servers MUST support local and remote (NFS) file:// scheme URLs in the recurl attribute. MSCML supports http:// and https:// scheme URLs indirectly through the <managecontent> (Section 8) request. π
The <faxrecord> request operates in one of three modes: receive, poll, and turnaround poll. The combination of <prompt> or prompturl attribute and recurl attribute defines the mode. Table 4 describes these modes in detail. The prompt column in the table has the value yes if the request has either a <prompt> element or a prompturl attribute. π¦
+--------+--------+---------+---------------------------------------+
| prompt | recurl | Mode | Operation |
+--------+--------+---------+---------------------------------------+
| no | no | Invalid | Request fails. |
| no | yes | Receive | Record the fax to the target URL |
| | | | specified in 'recurl'. |
| yes | no | Poll | Send fax from source specified in the |
| | | | <prompt> element or 'prompturl' |
| | | | attribute. If there is a 'rmtid', it |
| | | | MUST match the remote terminal's |
| | | | identifier, or the request will fail. |
| yes | yes | TP | Turnaround Poll (TP) mode. If the |
| | | | remote terminal wishes to transmit, |
| | | | the media server records the fax to |
| | | | the target URL specified in 'recurl'. |
| | | | If the remote terminal wishes to |
| | | | receive, the media server sends the |
| | | | fax from the source URL contained in |
| | | | <prompt> or 'prompturl'. If there is |
| | | | a 'rmtid', it MUST match remote |
| | | | terminal's identifier, or the send |
| | | | request will fail. A receive |
| | | | operation will still succeed, |
| | | | however. |
+--------+--------+---------+---------------------------------------+
Table 4: Fax Receive Modes
In receive mode, the media server receives the fax and writes the fax data to the target URL specified by the recurl attribute. π₯
In poll mode, the media server sends a fax, but as a polled (called) device. π€
In turnaround poll mode, the media server will record a fax that the remote machine sends. If the remote machine requests a transmission, then the media server will send the fax. πβ¨
When transmitting a fax, the media server will advertise that it can receive faxes in the DIS message. Likewise, when receiving a fax, the media server will advertise that it can send faxes in the DIS message. π£
The media server MUST flush any quarantined digits when it receives a <faxrecord> request. π§Ήπ
9.2. Sending a Fax <faxplay> π
okay so the <faxplay> request tells the media server to process a fax in originate mode π It gets its own request instead of just using <play> because the media server needs to know it's dealing with the T.30 [18] or T.38 [19] fax protocols. β¨ it's a whole different vibe, ngl
The <faxplay> request has a bunch of attributes and one child element, <prompt> π Here's the rundown of the attributes:
lclid- optional, default value""(the empty string): A string that identifies the called station.prompturl- optional, no default value: The URL of the content to be retrieved and played. The target can be a local or remote (NFS)"file://"scheme URL, or an"http://"or"https://"scheme URL. NOTE: Use of this attribute is deprecated.promptencoding- optional, no default value: Specifies the content encoding for files that don't have a 'tif' or 'tiff' extension. The only allowable value is'tiff'. This attribute only affects"file://"scheme URLs. NOTE: Use of this attribute is deprecated.recurl- optional, no default value: Specifies the target URL for the recorded content.rmtid- optional, no default value: Specifies the calling station identifier of the remote terminal. If present, the media server MUST reject transactions with the remote terminal if the remote terminal's identifier does not match the value of'rmtid'.
Clients SHOULD use the more flexible <prompt> mechanism for specifying fax content π«Ά Using the prompturl attribute is deprecated and may not be supported in future MSCML versions. The <prompt> element is described in Section 6.1.1. A <prompt> element sent in a <faxrecord> request MUST NOT contain <variable> elements. π
Media servers MUST support local and remote (NFS) "file://" scheme URLs in the recurl attribute. MSCML supports "http://" and "https://" scheme URLs indirectly through the <managecontent> (Section 8) request. πΈ
The <faxplay> request works in one of three modes: send, remote poll, and turnaround poll π¦ The combo of the <prompt> element or the prompturl attribute, plus the recurl attribute, is what decides the mode. Table 5 breaks it all down. The 'prompt' column is 'yes' if the request has either a <prompt> element or a prompturl attribute.
+--------+--------+---------+---------------------------------------+
| prompt | recurl | Mode | Operation |
+--------+--------+---------+---------------------------------------+
| no | no | Invalid | Request fails. |
| yes | no | Send | Send fax from source specified in the |
| | | | <prompt> element or 'prompturl' |
| | | | attribute. If there is a 'rmtid', it |
| | | | MUST match the remote terminal's |
| | | | identifier, or the request will fail. |
| no | yes | Poll | Send fax from source specified in the |
| | | | <prompt> element or 'prompturl' |
| | | | attribute, assuming the remote |
| | | | terminal specifies it can receive a |
| | | | fax in its DIS message. If the remote |
| | | | terminal does not support reverse |
| | | | polling, the request will fail. If |
| | | | 'rmtid' is specified, it MUST match |
| | | | remote terminal's identifier, or the |
| | | | request will fail. |
| yes | yes | TP | Turnaround Poll (TP) mode. If the |
| | | | remote terminal wishes to transmit, |
| | | | the media server records the fax to |
| | | | the target URL specified in 'recurl'. |
| | | | If the remote terminal wishes to |
| | | | receive, the media server sends the |
| | | | fax from the source URL contained in |
| | | | <prompt> or 'prompturl'. If there is |
| | | | a 'rmtid', it MUST match remote |
| | | | terminal's identifier, or the send |
| | | | request will fail. A receive |
| | | | operation will still succeed, |
| | | | however. |
+--------+--------+---------+---------------------------------------+
Table 5: Fax Send Modes
In send mode, the media server sends the fax. π€
In remote poll mode, the client places a call on behalf of the media server. The media server requests a fax transmission from the remote fax terminal. π
In turnaround poll mode, the media server records a fax that the remote machine sends. If the remote machine requests a transmission, the media server sends the fax. π
When transmitting a fax, the media server advertises that it can receive faxes in the DIS message. Likewise, when receiving a fax, the media server advertises that it can send faxes in the DIS message. π
The media server MUST flush any quarantined digits when it receives a <faxplay> request. π§Ή
10. MSCML Response Attributes and Elements π
10.1. Mechanism
The media server acknowledges receipt of a client MSCML request sent in a SIP INVITE by sending a response of either 200 OK or 415 Bad Media Type. It responds with 415 when the SIP request contains a content type other than "application/sdp" or "application/mediaservercontrol+xml". π
The media server acknowledges receipt of a client MSCML request sent in a SIP INFO with a 200 OK or 415 Bad Media Type. It responds with 415 if the INFO request contains a content type other than "application/mediaservercontrol+xml". β¨
The media server transports the MSCML <response> message in a SIP INFO request. π
If there's an error in the request, or the media server can't complete the request, the media server sends the <response> message very shortly after receiving the request. If the request is able to proceed, the <response> contains final status information, as described below. π
10.2. Base <response> Attributes
All MSCML responses have the basic attributes defined in the list below. π
Basic MSCML Response Attributes:
id- optional, no default value: Echoes the client-defined ID contained in the request.request- required, no default value: Specifies the MSCML request type that generated the response. Allowable values are"configure_conference","configure_leg","play","playcollect","playrecord","stop","faxplay","faxrecord", and"managecontent".code- required, no default value: The final status code for the request. MSCML uses a subset of the status classes defined in RFC 3261 [4]. In MSCML, 2XX responses indicate success, 4XX responses indicate client error, and 5XX responses indicate an error on the media server. There are no 1XX, 3XX, or 6XX status codes in MSCML.text- required, no default value: The human-readable reason phrase associated with the status code.
Responses to <configure_conference> and <stop> requests contain only the attributes above. MSCML responses to other requests MAY contain additional request-specific attributes and elements. These are described in the following sections. π§
10.3. Response Attributes and Elements for <configure_leg>
Responses to <configure_leg> requests have only the base response attributes defined in Section 10.2. However, when the request contains a <configure_team> element, the response includes a <team> element describing the teammate configuration for that leg. The attributes of the <team> element are shown in the list below. π―
Attributes of <team>:
id- required, no default value: The client-defined unique identifier for the conference leg.numteam- required, no default value: The number of team members for the leg.
Additional information on each team member is conveyed by child <teammate> elements contained within <team>. Each teammate is represented by a single element in the list. The <teammate> element has a single attribute, as described below. π«§
Attributes of <teammate>:
id- required, no default value: The client-defined unique identifier for the teammate leg.
10.4. Response Attributes and Elements for <play>
In addition to the base response attributes defined in Section 10.2, responses to <play> requests have the additional attributes described in the list below. πΆ
MSCML Response Attributes for <play>:
reason- optional, no default value: For requests that are not completed immediately, the"reason"attribute conveys additional information regarding why the command was completed. Possible values are"stopped", indicating that an explicit or implicit <stop> request was received, and"EOF", indicating that the end of the specified sequence of URLs was reached.playduration- required, no default value: A time value (Section 4.2.1) that returns the duration of the associated content playout. β±οΈplayoffset- required, no default value: A time value (Section 4.2.1) that returns the time offset into the specified content sequence where play was terminated. If the initial"offset"value in the sequence was"0", then"playduration"and"playoffset"are equal. However, if the initial offset had some other value,"playoffset"serves as a bookmark for the client to resume play in a subsequent request. π
10.4.1. Reporting Content Retrieval Errors
If the associated request set "stoponerror=yes" in <prompt> and an error occurred while retrieving the specified content, the response includes an <error_info> element detailing the problem. This element contains the response information received from the remote content server. The <error_info> element has the attributes described in the list below. π¨
Attributes of <error_info>:
code- required, no default value: The status code returned by the remote content server. For example, a web server might return 404 to indicate that the requested content was not found.text- required, no default value: The human-readable reason phrase returned by the remote content server. For example, the reason phrase "Not Found" would be returned if the requested content was not found.context- required, no default value: Contains the content URL that was being fetched when the retrieval error occurred. This enables the client to know precisely which URL in a sequence caused the problem. πΊοΈ
An <error_info> element MAY be present in the response to any request that contains a child <prompt> element. π
10.5. Response Attributes and Elements for <playcollect> π
Okay so, on top of the base response attributes from Section 10.2, <playcollect> responses get a few extra attributes of their own. Here's the lineup π
- reason (optional, no default value): For requests that don't finish right away,
reasontells you why the command wrapped up. The options are"stopped"(an explicit or implicit<stop>request came in π),"match"(a DTMF grammar got matched β ),"timeout"(no DTMF input showed up before one of the collection timers ran out β°), and"returnkey"or"escapekey"(the DTMF digit mapped to that key got detected, and that key ended the operation π). - playduration (required, no default value): A time value (Section 4.2.1) that tells you how long the associated content played πΆ. If the caller barged the prompt, this reflects the play duration up to that moment.
- playoffset (required, no default value): A time value (Section 4.2.1) showing the offset into the specified content sequence where play stopped β―οΈ. If the initial
"offset"in the sequence was"0", thenplaydurationandplayoffsetare the same. But if the starting offset was something else,playoffsetacts like a bookmark π so the client can pick up where it left off in a later request. If the caller barged in, this shows the exact offset where the barge-in happened. - digits (required, no default value): The collected DTMF input characters π’. If nothing got collected, this is just the empty string (
""). - name (required, see note, no default value): The client-defined name of the DTMF grammar that got matched π·οΈ. Note: this attribute is required if the
"name"attribute was set in the matching DTMF grammar.
Responses to <playcollect> requests MAY include an <error_info> element, as described in Section 10.4.1 π«Ά.
10.6. Response Attributes and Elements for <playrecord> ποΈ
Same deal here: on top of the base response attributes from Section 10.2, <playrecord> responses have their own extra attributes π.
- reason (optional, no default value): For requests that don't finish immediately,
reasonexplains why the command ended. The possible values are"stopped"(an explicit or implicit<stop>request arrived π),"digit"(a DTMF digit got detected and the prompt phase got barged π ),"init_silence"(the recording ended because there was no input π€«),"end_silence"(the recording ended because the"endsilence"timer elapsed β²οΈ),"max_duration"(the maximum recording time got reached β),"escapekey"(the DTMF input mapped to"escapekey"got detected, which ended the recording π), and"error"(a general operation failure π). - playduration (required, no default value): A time value (Section 4.2.1) showing how long the associated content played πΆ. If the caller barged the prompt, this reflects the play duration up to that event.
- playoffset (required, no default value): A time value (Section 4.2.1) showing the offset into the specified content sequence where play stopped β―οΈ. If the initial
"offset"in the sequence was"0", thenplaydurationandplayoffsetare equal. If the starting offset was different,playoffsetworks as a bookmark π for resuming play in a later request. If the caller barged in, this shows the offset where barge-in occurred. - digits (required, no default value): The DTMF digit that ended the recording π’. If no DTMF input got detected, this is the empty string (
""). - reclength (required, no default value): The length of the recorded content, in bytes π¦.
- recduration (required, no default value): A time value (Section 4.2.1) showing the elapsed duration of the recording β±οΈ.
Responses to <playrecord> requests MAY include an <error_info> element, as described in Section 10.4.1 πΈ.
10.7. Response Attributes and Elements for <managecontent> ποΈ
Responses to <managecontent> requests only have the base response attributes from Section 10.2, so no extras this time β¨. The one exception: if a content transfer error happens while the request runs, the response also includes an <error_info> element, as described in Section 10.4.1 π¨.
10.8. Response Attributes and Elements for <faxplay> and <faxrecord> π
Last one for this group π
. Responses to <faxplay> and <faxrecord> requests get the base response attributes from Section 10.2, plus these extras.
- reason (required, no default value): For requests that don't finish immediately,
reasonexplains why the command finished π. The options are"stopped"(an explicit or implicit<stop>request came in π),"complete"(successful completion, even if there were bad lines or minor negotiation hiccups, like a DCN showing up π),"disconnect"(the session got disconnected π΄), and"notfax"(no DIS or DCS came in on the connection π). - pages_received (required, see note, no default value): How many fax pages were received π. Note: this attribute is required if any pages were received.
- pages_sent (required, see note, no default value): How many fax pages were sent π€. Note: this attribute is required if any pages were sent.
- faxcode (required, no default value): The
faxcodevalue is the binary-or of the bit patterns listed in Table 6 π§©. Here's the table:
+------+--------------------------------------+
| Mask | description |
+------+--------------------------------------+
| 0 | Operation Failed |
| 1 | Operation Succeeded |
| 2 | Partial Success |
| 4 | Image received and placed in recurl |
| 8 | Image sent from specified source URL |
| 16 | rmtid did not match |
| 32 | Error reading source URL |
| 64 | Error writing recurl |
| 128 | Negotiation failure on send phase |
| 256 | Negotiation failure on receive phase |
| 512 | Reserved |
| 1024 | Irrecoverable IP packet loss |
| 2048 | Line errors in received image |
+------+--------------------------------------+
Table 6: Faxcode Mask
Responses to <faxplay> and <faxrecord> requests MAY include an <error_info> element, as described in Section 10.4.1 π¦.
11. Formal Syntax π§
Okay, this is the serious part π€. The syntax spec uses XML Schema, as described in XML [7].
11.1. Schema π
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="MediaServerControl">
<xs:complexType>
<xs:choice>
<xs:element name="request">
<xs:complexType>
<xs:choice>
<xs:element name="configure_conference"
type="configure_conferenceRequestType"/>
<xs:element name="configure_leg"
type="configure_legRequestType"/>
<xs:element name="play" type="playRequestType"/>
<xs:element name="playcollect"
type="playcollectRequestType"/>
<xs:element name="playrecord"
type="playrecordRequestType"/>
<xs:element name="managecontent"
type="managecontentRequestType"/>
<xs:element name="faxplay"
type="faxRequestType"/>
<xs:element name="faxrecord"
type="faxRequestType"/>
<xs:element name="stop" type="stopRequestType"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="response" type="responseType"/>
<xs:element name="notification">
<xs:complexType>
<xs:choice>
<xs:element name="conference"
type="conferenceNotificationType"/>
<xs:element name="keypress"
type="keypressNotificationType"/>
<xs:element name="signal"
type="signalNotificationType"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:choice>
<xs:attribute name="version" use="required"/>
</xs:complexType>
</xs:element>
<!-- Definitions for base and concrete MSCML requests -->
<!-- and embedded types. -->
<xs:complexType name="base_requestType" abstract="true">
<xs:attribute name="id" type="xs:string"/>
</xs:complexType>
<xs:complexType name="playRequestType">
<xs:complexContent>
<xs:extension base="base_requestType">
<xs:sequence>
<xs:element name="prompt" type="promptType"
minOccurs="0"/>
</xs:sequence>
<xs:attribute name="prompturl" type="xs:string"/>
<xs:attribute name="offset" type="xs:string"/>
<xs:attribute name="promptencoding" type="xs:string"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="configure_conferenceRequestType">
<xs:complexContent>
<xs:extension base="base_requestType">
Okay bestie, we're picking up right where the schema left off, and it's giving chaotic but organized πβ¨ Here's the next chunk of the XML, exactly as the RFC has it π
<xs:sequence>
<xs:element name="subscribe"
type="conference_eventsubscriptionType" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="reservedtalkers"
type="xs:positiveInteger"/>
<xs:attribute name="reserveconfmedia" type="yesnoType"
default="yes"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="configure_legRequestType">
<xs:complexContent>
<xs:extension base="base_requestType">
<xs:sequence>
<xs:element name="inputgain" type="gainType"
minOccurs="0"/>
<xs:element name="outputgain" type="gainType"
minOccurs="0"/>
<xs:element name="configure_team"
type="configure_teamType" minOccurs="0"/>
<xs:element name="subscribe"
type="leg_eventsubscriptionType" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="type">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="talker"/>
<xs:enumeration value="listener"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="mixmode">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="full"/>
<xs:enumeration value="mute"/>
<xs:enumeration value="preferred"/>
<xs:enumeration value="parked"/>
<xs:enumeration value="private"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="dtmfclamp" type="yesnoType"/>
<xs:attribute name="toneclamp" type="yesnoType"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="configure_teamType">
<xs:sequence>
<xs:element name="teammate" type="teammateType" minOccurs="0"
maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string"/>
<xs:attribute name="action" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="add"/>
<xs:enumeration value="delete"/>
<xs:enumeration value="query"/>
<xs:enumeration value="set"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
<xs:complexType name="teammateType">
<xs:attribute name="id" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="playcollectRequestType">
<xs:complexContent>
<xs:extension base="base_requestType">
<xs:sequence>
<xs:element name="prompt" type="promptType"
minOccurs="0"/>
<xs:element name="pattern" type="dtmfGrammarType"
minOccurs="0"/>
</xs:sequence>
<xs:attribute name="prompturl" type="xs:string"/>
<xs:attribute name="offset" type="xs:string"/>
<xs:attribute name="barge" type="yesnoType" default="yes"/>
<xs:attribute name="promptencoding" type="xs:string"/>
<xs:attribute name="cleardigits" type="yesnoType"
default="no"/>
<xs:attribute name="maxdigits" type="xs:string"/>
<xs:attribute name="firstdigittimer" type="xs:string"
default="5000ms"/>
<xs:attribute name="interdigittimer" type="xs:string"
default="2000ms"/>
<xs:attribute name="extradigittimer" type="xs:string"
default="1000ms"/>
<xs:attribute name="interdigitcriticaltimer"
type="xs:string"/>
<xs:attribute name="skipinterval" type="xs:string"
default="6s"/>
<xs:attribute name="ffkey" type="DTMFkeyType"/>
<xs:attribute name="rwkey" type="DTMFkeyType"/>
<xs:attribute name="returnkey" type="DTMFkeyType"
default="#"/>
<xs:attribute name="escapekey" type="DTMFkeyType"
default="*"/>
<xs:attribute name="maskdigits" type="yesnoType"
default="no"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="playrecordRequestType">
<xs:complexContent>
<xs:extension base="base_requestType">
<xs:sequence>
<xs:element name="prompt" type="promptType"
minOccurs="0"/>
</xs:sequence>
<xs:attribute name="prompturl" type="xs:string"/>
<xs:attribute name="promptencoding" type="xs:string"/>
<xs:attribute name="offset" type="xs:string" default="0"/>
<xs:attribute name="barge" type="yesnoType" default="yes"/>
<xs:attribute name="cleardigits" type="yesnoType"
default="no"/>
<xs:attribute name="escapekey" type="xs:string" default="*"/>
<xs:attribute name="recurl" type="xs:string" use="required"/>
<xs:attribute name="mode" default="overwrite">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="append"/>
<xs:enumeration value="overwrite"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="recencoding" type="xs:string"/>
<xs:attribute name="initsilence" type="xs:string"/>
<xs:attribute name="endsilence" type="xs:string"/>
<xs:attribute name="duration" type="xs:string"/>
<xs:attribute name="beep" type="yesnoType" default="yes"/>
<xs:attribute name="recstopmask" type="xs:string"
default="01234567890*#"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="managecontentRequestType">
<xs:complexContent>
<xs:extension base="base_requestType">
<xs:attribute name="fetchtimeout" type="xs:string"
default="10000"/>
<xs:attribute name="mimetype" type="xs:string"/>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="httpmethod">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="put"/>
<xs:enumeration value="post"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="action">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="move"/>
<xs:enumeration value="delete"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="dest" type="xs:string"/>
<xs:attribute name="src" type="xs:string" use="required"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="stopRequestType">
<xs:complexContent>
<xs:extension base="base_requestType"/>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="faxRequestType">
<xs:complexContent>
<xs:extension base="base_requestType">
<xs:sequence>
<xs:element name="prompt" type="promptType" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="lclid" type="xs:string"/>
<xs:attribute name="prompturl" type="xs:string"/>
<xs:attribute name="recurl" type="xs:string"/>
<xs:attribute name="rmtid" type="xs:string"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="dtmfGrammarType">
<xs:choice>
<xs:element name="regex" type="dtmfPatternType"
maxOccurs="unbounded"/>
<xs:element name="mgcpdigitmap" type="dtmfPatternType"/>
<xs:element name="megacodigitmap" type="dtmfPatternType"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="dtmfPatternType">
<xs:attribute name="value" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
<!-- Definitions for base and concrete MSCML responses -->
<!-- and embedded types. -->
<xs:complexType name="base_responseType" abstract="true">
<xs:attribute name="request" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="configure_conference"/>
<xs:enumeration value="configure_leg"/>
<xs:enumeration value="play"/>
<xs:enumeration value="playcollect"/>
<xs:enumeration value="playrecord"/>
<xs:enumeration value="managecontent"/>
<xs:enumeration value="faxplay"/>
<xs:enumeration value="faxrecord"/>
<xs:enumeration value="stop"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="id" type="xs:string"/>
<xs:attribute name="code" type="xs:string" use="required"/>
<xs:attribute name="text" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="responseType">
<xs:complexContent>
<xs:extension base="base_responseType">
<xs:sequence>
<xs:element name="error_info"
type="stoponerrorResponseType" minOccurs="0"/>
<xs:element name="team" type="configure_teamResponseType"
minOccurs="0"/>
</xs:sequence>
<xs:attribute name="reason" type="xs:string"/>
<xs:attribute name="reclength" type="xs:string"/>
<xs:attribute name="recduration" type="xs:string"/>
<xs:attribute name="digits" type="xs:string"/>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="playduration" type="xs:string"/>
<xs:attribute name="playoffset" type="xs:string"/>
<xs:attribute name="faxcode" type="xs:string"/>
<xs:attribute name="pages_sent" type="xs:string"/>
<xs:attribute name="pages_recv" type="xs:string"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="stoponerrorResponseType">
<xs:attribute name="code" type="xs:string" use="required"/>
<xs:attribute name="text" type="xs:string" use="required"/>
<xs:attribute name="context" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="configure_teamResponseType">
<xs:sequence>
<xs:element name="teammate" type="teammateType" minOccurs="0"
maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="numteam" type="xs:integer" use="required"/>
</xs:complexType>
<!-- Definitions for MSCML event subscriptions and -->
<!-- embedded types -->
<xs:complexType name="conference_eventsubscriptionType">
<xs:sequence>
<xs:element name="events">
<xs:complexType>
<xs:sequence>
<xs:element name="activetalkers"
type="activetalkersSubscriptionType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="activetalkersSubscriptionType">
<xs:attribute name="report" type="yesnoType" use="required"/>
<xs:attribute name="interval" type="xs:string" default="60s"/>
</xs:complexType>
<xs:complexType name="leg_eventsubscriptionType">
<xs:sequence>
<xs:element name="events">
<xs:complexType>
Ngl the request types in this chunk are giving main character energy π§πΈ We've got the conference, leg, playcollect, playrecord, managecontent, stop, and fax request shapes, plus the base response and the subscription bits π
<xs:sequence>
<xs:element name="keypress"
type="keypressSubscriptionType" minOccurs="0"
maxOccurs="1"/>
<xs:element name="signal" type="signalSubscriptionType"
minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="keypressSubscriptionType">
<xs:attribute name="report" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="standard"/>
<xs:enumeration value="long"/>
<xs:enumeration value="both"/>
<xs:enumeration value="none"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="maskdigits" type="yesnoType" default="no"/>
</xs:complexType>
<xs:complexType name="signalSubscriptionType">
<xs:attribute name="type" type="xs:NMTOKEN" use="required"/>
<xs:attribute name="report" type="yesnoType" use="required"/>
</xs:complexType>
<!-- Definitions for MSCML event notifications and -->
<!-- embedded types. -->
<xs:complexType name="conferenceNotificationType">
<xs:sequence>
<xs:element name="activetalkers"
type="activetalkersNotificationType" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="uniqueid" type="xs:string" use="required"/>
<xs:attribute name="numtalkers" type="xs:string"
use="required"/>
</xs:complexType>
<xs:complexType name="activetalkersNotificationType">
<xs:sequence minOccurs="0">
<xs:element name="talker" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="callid" type="xs:string"
use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="keypressNotificationType">
<xs:sequence>
<xs:element name="status" type="statusType"/>
</xs:sequence>
<xs:attribute name="digit" type="DTMFkeyType" use="required"/>
<xs:attribute name="length" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="standard"/>
<xs:enumeration value="long"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="method" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="standard"/>
<xs:enumeration value="long"/>
<xs:enumeration value="double"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="interdigittime" type="xs:string"
use="required"/>
</xs:complexType>
<xs:complexType name="statusType">
<xs:attribute name="command" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="idle"/>
<xs:enumeration value="play"/>
<xs:enumeration value="collect"/>
<xs:enumeration value="record"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="duration" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="signalNotificationType">
<xs:attribute name="type" use="required" fixed="busy"/>
</xs:complexType>
<!-- Definitions for miscellaneous embedded, helper data types -->
<xs:complexType name="promptType">
<xs:choice maxOccurs="unbounded">
<xs:element name="audio" type="promptcontentType"/>
<xs:element name="variable" type="spokenvariableType"/>
</xs:choice>
<xs:attribute name="locale" type="xs:string"/>
<xs:attribute name="baseurl" type="xs:string"/>
<xs:attribute name="stoponerror" type="yesnoType" default="no"/>
<xs:attribute name="gain" type="xs:string" default="0"/>
<xs:attribute name="gaindelta" type="xs:string" default="0"/>
<xs:attribute name="rate" type="xs:string" default="0"/>
<xs:attribute name="ratedelta" type="xs:string" default="0"/>
<xs:attribute name="repeat" type="xs:string" default="1"/>
<xs:attribute name="duration" type="xs:string"
default="infinite"/>
<xs:attribute name="offset" type="xs:string" default="0"/>
<xs:attribute name="delay" type="xs:string" default="0"/>
</xs:complexType>
<xs:complexType name="promptcontentType">
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="encoding" type="xs:string"/>
<xs:attribute name="gain" type="xs:string" default="0"/>
<xs:attribute name="gaindelta" type="xs:string" default="0"/>
<xs:attribute name="rate" type="xs:string" default="0"/>
<xs:attribute name="ratedelta" type="xs:string" default="0"/>
</xs:complexType>
<xs:complexType name="spokenvariableType">
<xs:attribute name="type" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="dat"/>
<xs:enumeration value="dig"/>
<xs:enumeration value="dur"/>
<xs:enumeration value="mth"/>
<xs:enumeration value="mny"/>
<xs:enumeration value="num"/>
<xs:enumeration value="sil"/>
<xs:enumeration value="str"/>
<xs:enumeration value="tme"/>
<xs:enumeration value="wkd"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="subtype">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="mdy"/>
<xs:enumeration value="dmy"/>
<xs:enumeration value="ymd"/>
<xs:enumeration value="ndn"/>
<xs:enumeration value="t12"/>
<xs:enumeration value="t24"/>
<xs:enumeration value="USD"/>
<xs:enumeration value="gen"/>
<xs:enumeration value="ndn"/>
<xs:enumeration value="crd"/>
<xs:enumeration value="ord"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="value" type="xs:string" use="required"/>
</xs:complexType>
<xs:simpleType name="yesnoType">
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="yes"/>
<xs:enumeration value="no"/>
<xs:enumeration value="1"/>
<xs:enumeration value="0"/>
<xs:enumeration value="true"/>
<xs:enumeration value="false"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="DTMFkeyType">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]"/>
<xs:pattern value="[A-D]"/>
<xs:pattern value="[a-d]"/>
<xs:pattern value="#"/>
<xs:pattern value="\*"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="gainType">
<xs:choice>
<xs:element name="auto" type="autogainType"/>
<xs:element name="fixed" type="fixedgainType"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="autogainType">
<xs:attribute name="startlevel" type="xs:string"/>
<xs:attribute name="targetlevel" type="xs:string"/>
<xs:attribute name="silencethreshold" type="xs:string"/>
</xs:complexType>
<xs:complexType name="fixedgainType">
<xs:attribute name="level" type="xs:string"/>
</xs:complexType>
</xs:schema>
And that's the whole schema wrapped up, bestie π π All those little types (keypress subscriptions, signal notifications, prompts, spoken variables, gain settings) are the building blocks everything else snaps together with. Iconic. π§
12. IANA Considerations π¦
12.1. IANA Registration of MIME Media Type application/mediaservercontrol+xml β¨
okay so IANA gets a little registration form for the new media type, and it goes like this π
MIME media type name: application
MIME subtype name: mediaservercontrol+xml
Required parameters: none
Optional parameters: charset
The only optional parameter is charset π and it means exactly the same thing as the charset parameter on application/xml, so go look at XML Media Types [8] if you want the full tea π«
The rest of the form is below, and it's giving very official vibes πΈ
Encoding considerations: See RFC 3023 [8].
Interoperability considerations: See RFC 2023 [8] and RFC 5022.
Published specification: RFC 5022
Applications that use this media type: Multimedia, enhanced
conferencing and interactive applications.
Personal and email address for further
information: eburger@cantata.com [31]
Intended usage: COMMON
Main character energy: this media type is for multimedia, enhanced conferencing and interactive apps, and its published spec is RFC 5022 itself πβ¨
13. Security Considerations πβ¨
Okay bestie, security is SERIOUS π Media flows through a media server in a conference, so the media server itself MUST protect the integrity, confidentiality, and security of the sessions. It should not be possible for a conference participant, acting on her own behalf, to "tap in" to another conference without proper authorization π ββοΈ
Conferencing is a high-value app, so the media server SHOULD implement appropriate security measures π That includes, but isn't limited to, access lists for application servers. So the media server only lets a select list of application or proxy servers create conferences, invite participants to sessions, and so on. Mechanisms for this, like private networks, shared certificates, and MAC white/black lists, are beyond the scope of this document π§±
Security is one big reason MSCML limits requests with conference scope to a separate control leg per conference π MSCML uses the simple, proven, Internet-scale security model of SIP to figure out if a client is who they say they are (authentication) and if they're allowed to create and manipulate a conference. BUT the security model that lets a control leg manipulate arbitrary conferences on the media server is extremely difficult π© You'd need to authenticate and authorize the basic conference primitives, and privacy considerations also need policies for one client to access another client's conferences, even when both clients are on the same host. Like, if the media server let any control leg control any conference, an authorized but unrelated client could attach itself to a live session and record or tap the conversation without the participant knowing or consenting. Not it π
Participants give implicit authorization to their apps by way of the INVITE to the application. However, there is no trust, explicit or implicit, between the users of one service and a separate client of another service π«π€
All MSCML messages are sent within an INVITE-created SIP dialog. So it'd be hard for anyone other than the original requestor to interfere with an established MSCML session, since they'd need detailed information on the dialog state π΅οΈββοΈ This means multiple applications can use the resources of a single media server at the same time without messing with each other π
Because collected data can be super sensitive (think credit card numbers or other identifying info), the media server MUST support sips: and TLS π Clients presumably know the value of what they collect and what their users expect for privacy, so they're free to use clear text signaling or encrypted secure signaling, depending on what the application needs. Likewise, the media server SHOULD support Secure Realtime Transport Protocol (SRTP) [9]. Again, clients are free to negotiate the right level of media security π«Ά
The media management features of MSCML, like the <managecontent> (Section 8) request, assume a trust relationship between the media server and the file server. This is similar to the situation URLAUTH [20] deals with. The media server is acting on behalf of a given user, but it doesn't have that user's credentials π¬ You might be tempted to use the user:pass facility of the HTTP URI for per-user security, but that also requires the media server to be secure, since it would need to hold user credentials in a form that's really easy to compromise (clear text passwords) π
The IETF is still investigating ways to provide per-user or per-instance authorization for third-party HTTP writing, which other protocols need too, like WEBDAV [21]. Until that work is done, media server implementations MUST be prepared to authenticate themselves to file and web servers using appropriate authentication means. At a minimum, the media server MUST support HTTPS basic authentication. Implementers should note that the media server will need to respond appropriately to whatever authentication mechanism the file server requires π¨
Since this is XML markup, all the security considerations of RFC 3023 [8] apply π
14. References π
14.1. Normative References
- [1] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
- [2] Burger, E., Van Dyke, J., and A. Spitzer, "Basic Network Media Services with SIP", RFC 4240, December 2005.
- [3] Donovan, S., "The SIP INFO Method", RFC 2976, October 2000.
- [4] 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.
- [5] "Network call signalling protocol for the delivery of time-critical services over cable television networks using cable modems", ITU-T J.162, March 2001.
- [6] Groves, C., Pantaleo, M., Anderson, T., and T. Taylor, "Gateway Control Protocol Version 1", RFC 3525, June 2003.
- [7] Thompson, H., Beech, D., Maloney, M., and N. Mendelsohn, "XML Schema Part 1: Structures", W3C REC REC-xmlschema-1-20010502, May 2001.
- [8] Murata, M., St. Laurent, S., and D. Kohn, "XML Media Types", RFC 3023, January 2001.
- [9] Baugher, M., McGrew, D., Naslund, M., Carrara, E., and K. Norrman, "The Secure Real-time Transport Protocol (SRTP)", RFC 3711, March 2004.
14.2. Informative References
- [10] Rosenberg, J., "A Framework for Conferencing with the Session Initiation Protocol (SIP)", RFC 4353, February 2006.
- [11] Carter, J., Danielsen, P., Hunt, A., Ferrans, J., Lucas, B., Porter, B., Rehor, K., Tryphonas, S., McGlashan, S., and D. Burnett, "Voice Extensible Markup Language (VoiceXML) Version 2.0", W3C REC REC-voicexml20-20040316, March 2004.
- [12] International Packet Communications Consortium, "IPCC Reference Architecture V2", June 2002.
- [13] European Telecommunications Standards Institute, "Digital cellular telecommunications system (Phase 2+); Universal Mobile Telecommunications System (UMTS); IP Multimedia Subsystem (IMS); Stage 2 (3GPP TS 23.228 version 7.2.0 Release 7)", December 2005.
- [14] Hollenbeck, S., Rose, M., and L. Masinter, "Guidelines for the Use of Extensible Markup Language (XML) within IETF Protocols", BCP 70, RFC 3470, January 2003.
- [15] Jacobs, I., Lie, H., Bos, B., and C. Lilley, "Cascading Style Sheets, level 2 (CSS2) Specification", W3C REC REC-CSS2-19980512, May 1998.
- [16] Rosenberg, J., Schulzrinne, H., and O. Levin, "A Session Initiation Protocol (SIP) Event Package for Conference State", RFC 4575, August 2006.
- [17] Cable Television Laboratories, Inc., "Audio Server Protocol", January 2005.
- [18] "Procedures for document facsimile transmission in the general switched telephone network", Recommendation T.30, April 1999.
- [19] "Procedures for real-time Group 3 facsimile communication over IP networks", Recommendation T.38, March 2002.
- [20] Crispin, M., "Internet Message Access Protocol (IMAP) - URLAUTH Extension", RFC 4467, May 2006.
- [21] Dusseault, L., Ed., "HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)", RFC 4918, June 2007.
- [22] Institute of Electrical and Electronics Engineers, "Information Technology - Portable Operating System Interface (POSIX) - Part 1: Base Definitions, Chapter 9", IEEE Standard 1003.1, June 2001.
- [23] Burger, E. and M. Dolly, "A Session Initiation Protocol (SIP) Event Package for Key Press Stimulus (KPML)", RFC 4730, November 2006.
- [24] Klensin, J., "Simple Mail Transfer Protocol", RFC 2821, April 2001.
- [25] Campbell, B., Ed., Mahy, R., Ed., and C. Jennings, Ed., "The Message Session Relay Protocol", Work in Progress, February 2007.
URIs
- [26]
<http://www.ietf.org/html.charters/sip-charter.html> - [27]
<http://www.ietf.org/html.charters/sipping-charter.html> - [28]
<http://www.ietf.org/html.charters/mmusic.html> - [29]
<http://www.ietf.org/html.charters/xcon-charter.html> - [30]
<http://www.3gpp.org/ftp/Specs/html-info/23228.htm> - [31]
<mailto:eburger@cantata.com>
Appendix A. Regex Grammar Syntax π’
The regular expression syntax used in MSCML is a telephony-oriented subset of POSIX Extended Regular Expressions (ERE) [22], and it's called Digit REGular EXpression (DRegex) π This syntax was first described in KPML [23].
DRegex covers ordinary characters, special characters, bracket expressions, and interval expressions. Here are those entities, defined in the list below π
. matches digits 0-9, *, #, and A-D (case insensitive)
* matches the * character
# matches the # character
[character selector] matches any character in selector
[range1-range2] matches any character in range from range1 to range2,
inclusive
x matches any digit 0-9
{m} matches m repetitions of the previous pattern
{m,} matches m or more repetitions of the previous pattern
{,n} matches at most n (including zero) repetitions of the previous
pattern
{m,n} at least m and at most n repetitions of the previous pattern
L the presence of 'L' in any regex expression causes the media
server to enable "long" digit detection mode. See Section 7.1 for
the definition of "long" digits.
Table 7 shows DRegex in action with some examples πΈ
+--------------+--------------------------------------------+
| Example | Description |
+--------------+--------------------------------------------+
| 1 | Matches the digit 1 |
| [179] | Matches 1, 7, or 9 |
| [2-9] | Matches 2, 3, 4, 5, 6, 7, 8, 9 |
| [02-46-9A-D] | Matches 0, 2, 3, 4, 6, 7, 8, 9, A, B, C, D |
| x | Matches 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 |
| . | Matches 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B,|
| | C, D, #, * |
| *6[179#] | Matches *61, *67, *69, or *6# |
| x{10} | Ten digits (0-9) |
| 011x{7,15} | 011 followed by seven to fifteen digits |
| L* | Long star |
+--------------+--------------------------------------------+
Table 7: DRegex Examples
Appendix B. Contributors π
Jeff Van Dyke and Andy Spitzer did the concept, development, documentation, and execution for MSCML at SnowShore Networks, Inc., which is now part of Cantata Technology, Inc. π Andy Spitzer's original work at The Telephone Connection, Inc., influenced the IVR implementation. Mary Ann Leekley implemented the personalized mix feature and several other enhancements π
Cliff Schornak of Commetrex and Jeff Van Dyke developed the facsimile service π
Jai Cauvet, Rolando Herrero, Srinivas Motamarri, and Ashish Patel contributed greatly by testing MSCML π§ͺπ«Ά
Appendix C. Acknowledgements π
okay bestie, time for the thank-you section! π«Ά These people helped with the direction, development, or debugging of MSCML, and they all deserve a shoutout:
- Brian Badger and Phil Crable from Verizon Business
- Stephane Bastien from BroadSoft
- Peter Danielsen of Lucent Technologies
- Kevin Flemming, formerly of SnowShore Networks, Inc.
- Wesley Hicks and Ravindra Kabre, formerly from Sonus Networks
- Jon Hinckley from SkyWave/Sestro
- Terence Lobo, formerly of SnowShore Networks, Inc.
- Kunal Nawale, formerly of SnowShore Networks, Inc.
- Edwina Nowicki, formerly of SnowShore Networks, Inc.
- Diana Rawlins and Sharadha Vijay, formerly of WorldCom
- Gaurav Srivastva and Subhash Verma from BayPackets
- Kevin Summers from Sonus Networks
- Tim Wong from at&t
The authors also want to thank Cullen Jennings and Dan Wing from Cisco Systems for their super helpful review comments π. And they gave a big thank-you to Scotty Farber, who used her technical writing skills to document MSCML so it's actually readable πβ¨. Literally iconic. π
Authors' Addresses π
Jeff Van Dyke Cantata Technology, Inc. 18 Keewaydin Dr. Salem, NH 03079 USA
EMail: jvandyke@cantata.com
Eric Burger (editor) BEA Systems, Inc. USA
Email: eburger@standardstrack.com URI: http://www.standardstrack.com
Andy Spitzer Bluesocket Inc. 10 North Avenue Burlington, MA 01803 USA
EMail: woof@pingtel.com
Full Copyright Statement π
Copyright (C) The IETF Trust (2007).
okay so this part is the legal stuff π but it still matters, so here it is. This document is subject to the rights, licenses and restrictions in BCP 78 and at www.rfc-editor.org/copyright.html. Except for what's set out there, the authors keep all their rights π¦.
This document and the information in it are provided on an "AS IS" basis, and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST, AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. π
Intellectual Property π¦
The IETF takes no position on whether any Intellectual Property Rights or other rights that someone might claim over the technology in this document are valid or in scope, or on whether a license to those rights is available. It also doesn't say it has done any independent search for such rights π. If you want the procedures for rights in RFC documents, check BCP 78 and BCP 79.
Copies of IPR disclosures made to the IETF Secretariat, and any assurances of licenses to be made available, or the results of an attempt to get a general license or permission to use such proprietary rights by implementers or users of this specification, can be found in the IETF's online IPR repository at http://www.ietf.org/ipr β¨.
The IETF invites any interested party to bring to its attention any copyrights, patents, patent applications, or other proprietary rights that may cover technology needed to implement this standard. Send that information to the IETF at ietf-ipr@ietf.org π. Thank you, bestie! π§
π¦ where this page comes from
- ietf: rfc5022 2007-09
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms