RFC 3435
Media Gateway Control Protocol (MGCP) Version 1.0
RFC 3435: Media Gateway Control Protocol (MGCP) Version 1.0 ๐ (Part 1 of 44)
okay bestie, this one is the MGCP spec, which is basically how a phone-call brain tells a bunch of gateways what to do ๐โจ
Authors: F. Andreasen and B. Foster, both from Cisco Systems ๐ Category: Informational ๐ง Date: January 2003 ๐ Obsoletes: RFC 2705 ๐ (so 2705 is officially retired and this is the new-and-improved version ๐ )
Status of this Memo ๐ซถ
so this doc is just here to inform the internet community, not to be a formal internet standard of any kind ๐ธ and you're allowed to distribute it as much as you want, no limits ๐ฆ
Copyright Notice ๐
Copyright (C) The Internet Society (2003). All Rights Reserved. ๐
IESG Note ๐
this doc got published so the community can know about a protocol that's already showing up in a bunch of products ๐๏ธ if you're implementing stuff, you should know about RFC 3015 โจ it came out of the IETF Megaco Working Group and the ITU-T SG16, and the IETF and ITU-T both see it as the standards-based way to cover what MGCP was built for. that includes the reviewed security considerations, which is a big deal ๐
Abstract ๐ง
okay so this doc describes an application programming interface and a protocol called MGCP, which runs between the parts of a decomposed multimedia gateway ๐๐ that gateway has two main pieces. first, there's the Call Agent, which holds the call control "intelligence" (the brain, literally ๐ง ). second, there's the media gateway, which handles the media functions, like turning TDM voice into Voice over IP ๐ฅ
media gateways have endpoints, and the Call Agent can create, modify, and delete connections on those endpoints so media sessions can get set up and controlled with other multimedia endpoints ๐ฆ the Call Agent can also tell endpoints to detect certain events and generate signals ๐ and when a service state changes, the endpoints automatically tell the Call Agent ๐ซถ on top of that, the Call Agent can audit the endpoints and the connections on them too ๐
the basic, general MGCP protocol is all defined in this document ๐ธ but most media gateways will need one or more MGCP packages too. packages are extensions to the protocol that fit specific kinds of media gateways, and they're defined in separate documents ๐ so yes, you'll be reading more than one doc, periodt ๐
Table of Contents ๐
1. Introduction.................................................5
1.1 Relation with the H.323 Standards............................7
1.2 Relation with the IETF Standards.............................8
1.3 Definitions..................................................9
1.4 Conventions used in this Document............................9
2. Media Gateway Control Interface.............................10
2.1 Model and Naming Conventions................................10
2.1.1 Types of Endpoints..........................................10
2.1.2 Endpoint Identifiers........................................14
2.1.3 Calls and Connections.......................................16
2.1.4 Names of Call Agents and Other Entities.....................22
2.1.5 Digit Maps..................................................23
2.1.6 Packages....................................................26
2.1.7 Events and Signals..........................................28
2.2 Usage of SDP................................................33
2.3 Gateway Control Commands....................................33
2.3.1 Overview of Commands........................................33
2.3.2 EndpointConfiguration.......................................36
2.3.3 NotificationRequest.........................................37
2.3.4 Notify......................................................44
2.3.5 CreateConnection............................................46
2.3.6 ModifyConnection............................................52
2.3.7 DeleteConnection (from the Call Agent)......................54
2.3.8 DeleteConnection (from the gateway).........................58
2.3.9 DeleteConnection (multiple connections from the Call Agent) 59
2.3.10 AuditEndpoint...............................................60
2.3.11 AuditConnection.............................................65
2.3.12 RestartInProgress...........................................66
2.4 Return Codes and Error Codes................................69
2.5 Reason Codes................................................74
2.6 Use of Local Connection Options and Connection Descriptors..75
2.7 Resource Reservations.......................................77
3. Media Gateway Control Protocol..............................77
3.1 General Description.........................................78
3.2 Command Header..............................................79
3.2.1 Command Line................................................79
3.2.2 Parameter Lines.............................................82
3.3 Format of response headers.................................101
3.3.1 CreateConnection Response..................................104
3.3.2 ModifyConnection Response..................................105
3.3.3 DeleteConnection Response..................................106
3.3.4 NotificationRequest Response...............................106
3.3.5 Notify Response............................................106
3.3.6 AuditEndpoint Response.....................................106
3.3.7 AuditConnection Response...................................107
3.3.8 RestartInProgress Response.................................108
3.4 Encoding of the Session Description (SDP)..................108
3.4.1 Usage of SDP for an Audio Service..........................110
3.4.2 Usage of SDP for LOCAL Connections.........................110
3.5 Transmission over UDP......................................111
3.5.1 Providing the At-Most-Once Functionality...................112
3.5.2 Transaction Identifiers and Three Ways Handshake...........113
3.5.3 Computing Retransmission Timers............................114
3.5.4 Maximum Datagram Size, Fragmentation and Reassembly........115
3.5.5 Piggybacking...............................................116
3.5.6 Provisional Responses......................................117
4. States, Failover and Race Conditions.......................119
4.1 Failover Assumptions and Highlights........................119
4.2 Communicating with Gateways................................121
4.3 Retransmission, and Detection of Lost Associations:........122
4.4 Race Conditions............................................126
4.4.1 Quarantine List............................................127
4.4.2 Explicit Detection.........................................133
4.4.3 Transactional Semantics....................................134
4.4.4 Ordering of Commands, and Treatment of Misorder............135
4.4.5 Endpoint Service States....................................137
4.4.6 Fighting the Restart Avalanche.............................140
4.4.7 Disconnected Endpoints.....................................143
4.4.8 Load Control in General....................................146
5. Security Requirements......................................147
5.1 Protection of Media Connections............................148
6. Packages...................................................148
6.1 Actions....................................................150
6.2 BearerInformation..........................................150
6.3 ConnectionModes............................................151
6.4 ConnectionParameters.......................................151
6.5 DigitMapLetters............................................151
6.6 Events and Signals.........................................152
6.6.1 Default and Reserved Events................................155
6.7 ExtensionParameters........................................156
6.8 LocalConnectionOptions.....................................157
6.9 Reason Codes...............................................157
6.10 RestartMethods.............................................158
6.11 Return Codes...............................................158
7. Versions and Compatibility.................................158
7.1 Changes from RFC 2705......................................158
8. Security Considerations....................................164
9. Acknowledgments............................................164
10. References.................................................164
Appendix A: Formal Syntax Description of the Protocol.............167
Appendix B: Base Package..........................................175
B.1 Events.....................................................175
B.2 Extension Parameters.......................................176
B.2.1 PersistentEvents...........................................176
B.2.2 NotificationState..........................................177
B.3 Verbs......................................................177
Appendix C: IANA Considerations...................................179
C.1 New MGCP Package Sub-Registry..............................179
C.2 New MGCP Package...........................................179
C.3 New MGCP LocalConnectionOptions Sub-Registry...............179
Appendix D: Mode Interactions.....................................180
Appendix E: Endpoint Naming Conventions...........................182
E.1 Analog Access Line Endpoints...............................182
E.2 Digital Trunks.............................................182
E.3 Virtual Endpoints..........................................183
E.4 Media Gateway..............................................184
E.5 Range Wildcards............................................184
Appendix F: Example Command Encodings.............................185
F.1 NotificationRequest........................................185
F.2 Notify.....................................................186
F.3 CreateConnection...........................................186
F.4 ModifyConnection...........................................189
F.5 DeleteConnection (from the Call Agent).....................189
F.6 DeleteConnection (from the gateway)........................190
F.7 DeleteConnection (multiple connections
from the Call Agent).......................................190
F.8 AuditEndpoint..............................................191
F.9 AuditConnection............................................192
F.10 RestartInProgress..........................................193
Appendix G: Example Call Flows....................................194
G.1 Restart....................................................195
G.1.1 Residential Gateway Restart................................195
G.1.2 Call Agent Restart.........................................198
G.2 Connection Creation........................................200
G.2.1 Residential Gateway to Residential Gateway.................200
G.3 Connection Deletion........................................206
G.3.1 Residential Gateway to Residential Gateway.................206
Authors' Addresses................................................209
Full Copyright Statement..........................................210
1. Introduction ๐ฆ
okay so this doc describes an abstract application programming interface (MGCI) and a corresponding protocol (MGCP) for controlling media gateways from external call control elements called media gateway controllers or Call Agents ๐. a media gateway is basically a network element that converts between the audio signals on telephone circuits and the data packets that travel over the Internet or other packet networks. the types of media gateways are:
- Trunking gateways ๐ธ, that interface between the telephone network and a Voice over IP network. these gateways typically manage a large number of digital circuits.
- Voice over ATM gateways โจ, which work pretty much the same way as voice over IP trunking gateways, except they interface to an ATM network.
- Residential gateways ๐, that provide a traditional analog (RJ11) interface to a Voice over IP network. examples of residential gateways include cable modem/cable set-top boxes, xDSL devices, and broad-band wireless devices.
- Access gateways ๐ง, that provide a traditional analog (RJ11) or digital PBX interface to a Voice over IP network. examples of access gateways include small-scale voice over IP gateways.
- Business gateways ๐ผ, that provide a traditional digital PBX interface or an integrated "soft PBX" interface to a Voice over IP network.
- Network Access Servers ๐, that can attach a "modem" to a telephone circuit and provide data access to the Internet. we expect that in the future, the same gateways will combine Voice over IP services and Network Access services. ๐
- Circuit switches, or packet switches โญ, which can offer a control interface to an external call control element.
MGCP assumes a call control architecture where the call control "intelligence" is outside the gateways and handled by external call control elements known as Call Agents ๐ . the MGCP assumes that these call control elements, or Call Agents, will synchronize with each other to send coherent commands and responses to the gateways under their control. if this assumption is violated, inconsistent behavior should be expected ๐. MGCP does not define a mechanism for synchronizing Call Agents. MGCP is, in essence, a master/slave protocol, where the gateways are expected to execute commands sent by the Call Agents. so this document specifies in great detail the expected behavior of the gateways, but only specifies those parts of a Call Agent implementation, such as timer management, that are mandated for proper operation of the protocol ๐ซถ.
MGCP assumes a connection model where the basic constructs are endpoints and connections ๐ฅ. endpoints are sources and/or sinks of data and can be physical or virtual. examples of physical endpoints are:
- An interface on a gateway that terminates a trunk connected to a PSTN switch (e.g., Class 5, Class 4, etc.). A gateway that terminates trunks is called a trunking gateway.
- An interface on a gateway that terminates an analog POTS connection to a phone, key system, PBX, etc. A gateway that terminates residential POTS lines (to phones) is called a residential gateway.
an example of a virtual endpoint is an audio source in an audio-content server. creating physical endpoints requires hardware installation, while creating virtual endpoints can be done by software ๐.
connections may be either point to point or multipoint. a point to point connection is an association between two endpoints with the purpose of transmitting data between these endpoints. once this association is established for both endpoints, data transfer between these endpoints can take place. a multipoint connection is established by connecting the endpoint to a multipoint session ๐ฆ.
connections can be established over several types of bearer networks, for example:
- Transmission of audio packets using RTP and UDP over an IP network.
- Transmission of audio packets using AAL2, or another adaptation layer, over an ATM network.
- Transmission of packets over an internal connection, for example the TDM backplane or the interconnection bus of a gateway. This is used, in particular, for "hairpin" connections, connections that terminate in a gateway but are immediately rerouted over the telephone network ๐.
for point-to-point connections, the endpoints of a connection could be in separate gateways or in the same gateway โจ.
1.1 Relation with the H.323 Standards ๐
MGCP is designed as an internal protocol within a distributed system that appears to the outside as a single VoIP gateway ๐. this system is composed of a Call Agent, that may or may not be distributed over several computer platforms, and of a set of gateways, including at least one "media gateway" that performs the conversion of media signals between circuits and packets, and at least one "signaling gateway" when connecting to an SS7 controlled network. in a typical configuration, this distributed gateway system will interface on one side with one or more telephony (i.e., circuit) switches, and on the other side with H.323 conformant systems, as shown in the following table ๐ธ:
------------------------------------------------------------------
| Functional| Phone | Terminating | H.323 conformant |
| Plane | switch | Entity | systems |
|-----------|------------|-----------------|-----------------------|
| Signaling | Signaling | Call agent | Signaling exchanges |
| Plane | exchanges | | with the Call Agent |
| | through | | through H.225/RAS and|
| | SS7/ISUP | | H.225/Q.931. |
|-----------|------------|-----------------|-----------------------|
| | | | Possible negotiation |
| | | | of logical channels |
| | | | and transmission |
| | | | parameters through |
| | | | H.245 with the call |
| | | | agent. |
|-----------|------------|-----------------|-----------------------|
| | | Internal | |
| | | synchronization| |
| | | through MGCP | |
|-----------|------------|-----------------|-----------------------|
| Bearer | Connection| Telephony | Transmission of VoIP |
| Data | through | gateways | data using RTP |
| Transport | high speed| | directly between the |
| Plane | trunk | | H.323 station and the|
| | groups | | gateway. |
------------------------------------------------------------------
in the MGCP model, the gateways focus on the audio signal translation function, while the Call Agent handles the call signaling and call processing functions ๐ . as a result, the Call Agent implements the "signaling" layers of the H.323 standard, and presents itself as an "H.323 Gatekeeper" or as one or more "H.323 Endpoints" to the H.323 systems ๐.
1.2 Relation with the IETF Standards ๐
while H.323 is the recognized standard for VoIP terminals, the IETF has also produced specifications for other types of multi-media applications โญ. these other specifications include:
- the Session Description Protocol (SDP), RFC 2327
- the Session Announcement Protocol (SAP), RFC 2974
- the Session Initiation Protocol (SIP), RFC 3261
- the Real Time Streaming Protocol (RTSP), RFC 2326.
the latter three specifications are actually alternative signaling standards that allow for the transmission of a session description to an interested party ๐ฆ. SAP is used by multicast session managers to distribute a multicast session description to a large group of recipients, SIP is used to invite an individual user to take part in a point-to-point or unicast session, and RTSP is used to interface a server that provides real time data ๐. in all three cases, the session description is described according to SDP. when audio is transmitted, it is transmitted through the Real-time Transport Protocol, RTP ๐ง.
the distributed gateway systems and MGCP will enable PSTN telephony users to access sessions set up using SAP, SIP or RTSP ๐ซถ. the Call Agent provides for signaling conversion, according to the following table:
------------------------------------------------------------------
| Functional| Phone | Terminating | IETF conforming systems|
| Plane | switch | Entity | |
|-----------|------------|---------------|-------------------------|
| Signaling | Signaling | Call agent | Signaling exchanges |
| Plane | exchanges | | with the Call Agent |
| | through | | through SAP, SIP or |
| | SS7/ISUP | | RTSP. |
|-----------|------------|---------------|-------------------------|
| | | | Negotiation of session |
| | | | description parameters |
| | | | through SDP (telephony |
| | | | gateway terminated but |
| | | | passed via the call |
| | | | agent to and from the |
| | | | IETF conforming system)|
|-----------|------------|---------------|-------------------------|
| | | Internal syn- | |
| | | chronization | |
| | | through MGCP | |
|-----------|------------|---------------|-------------------------|
| Bearer | Connection| Telephony | Transmission of VoIP |
| Data | through | gateways | data using RTP, |
| Transport | high speed| | directly between the |
| Plane | trunk | | remote IP end system |
| | groups | | and the gateway. |
------------------------------------------------------------------
the SDP standard has a pivotal status in this architecture ๐. we will see in the following description that we also use it to carry session descriptions in MGCP โจ.
1.3 Definitions ๐
- Trunk ๐: a communication channel between two switching systems, e.g., a DS0 on a T1 or E1 line.
1.4 Conventions used in this Document ๐
the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED, "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14, RFC 2119 [2] ๐ฅ.
2. Media Gateway Control Interface ๐
the interface functions provide for connection control and endpoint control ๐ธ. both use the same system model and the same naming conventions โจ.
2.1 Model and Naming Conventions ๐
the MGCP assumes a connection model where the basic constructs are endpoints and connections ๐ฆ. connections are grouped in calls. one or more connections can belong to one call. connections and calls are set up at the initiative of one or more Call Agents ๐.
2.1.1 Types of Endpoints โจ
okay so remember those gateway classes from the intro? "trunking," "access," and "residential"? bestie, those labels are kinda misleading ๐ Manufacturers can mix and match in one box. A single product could have some trunk connections to telephony switches, some primary rate connections, and some analog line interfaces, so it's sharing vibes with all three of those classes ๐ MGCP doesn't assume any groupings. We just assume media gateways support collections of endpoints, and the type of the endpoint decides its functionality ๐ Based on our analysis so far, these are the basic endpoint types:
- Digital channel (DS0)
- Analog line
- Announcement server access point
- Interactive Voice Response access point
- Conference bridge access point
- Packet relay
- ATM "trunk side" interface
Next up, we describe how these endpoints are expected to behave ๐ง
The list isn't final, babe. More types could show up later, like test endpoints for checking network quality, or frame-relay endpoints for managing audio channels multiplexed over a frame-relay virtual circuit ๐ฆ
2.1.1.1 Digital Channel (DS0)
Digital channels give you a 64 Kbps service ๐ You'll find them on trunk and ISDN interfaces, usually as part of digital multiplexes like T1, E1, T3, or E3 interfaces. Gateways that support these can translate the digital signals on the channel into audio packets. Those signals may be A-law or mu-law encoded, and they can use the complete set of 8 bits per sample or only 7 of those bits. When the gateway also supports a Network Access Server (NAS) service, it shall be capable of receiving either audio-encoded data (modem connection) or binary data (ISDN connection) and converting them into data packets.
+-------
+------------+|
(channel) ===|DS0 endpoint| -------- Connections
+------------+|
+-------
Media gateways should be able to establish several connections between the endpoint and the packet networks, or between the endpoint and other endpoints in the same gateway ๐ The signals from these connections shall be mixed according to the connection "mode," which we'll cover later in this document. How many connections an endpoint supports is a characteristic of the gateway, and it may vary depending on how resources get allocated inside the gateway.
Some digital channels carry signaling, like SS7 "F" links or ISDN "D" channels. Gateways that support these shall be able to send and receive signaling packets to and from a Call Agent, using the "backhaul" procedures defined by the SIGTRAN working group of the IETF ๐ฅ Digital channels are also sometimes used with channel associated signaling, like "MF R2." Gateways that support these functions shall be able to detect and produce the matching signals, such as "wink" or "A," following the event signaling and reporting procedures defined in MGCP.
2.1.1.2 Analog Line
Analog lines can work as a "client" interface that serves a classic telephone unit, or as a "service" interface that lets the gateway send and receive analog calls ๐ When the gateway also supports a NAS service, it shall be capable of receiving audio-encoded data (modem connection) and converting it into data packets.
+-------
+---------------+|
(line) ===|analog endpoint| -------- Connections
+---------------+|
+-------
Media gateways should be able to establish several connections between the endpoint and the packet networks, or between the endpoint and other endpoints in the same gateway โจ The audio signals from these connections shall be mixed according to the connection "mode," as specified later on. The precise number of connections is a gateway characteristic that may vary with how resources are allocated. A typical gateway should, however, be able to support two or three connections per endpoint, so services like "call waiting" or "three way calling" can work ๐ซถ
2.1.1.3 Announcement Server Access Point
An announcement server endpoint gives you access to an announcement service ๐ถ When the Call Agent asks, the announcement server will "play" a specified announcement. These requests follow the event signaling and reporting procedures defined in MGCP.
+----------------------+
| Announcement endpoint| -------- Connection
+----------------------+
A given announcement endpoint isn't expected to support more than one connection at a time. If several connections were set up to the same endpoint, then the same announcements would be played simultaneously over all of them ๐
Connections to an announcement server are typically one way, or "half duplex" -- the announcement server isn't expected to listen to the audio signals from the connection ๐ธ
2.1.1.4 Interactive Voice Response Access Point
An Interactive Voice Response (IVR) endpoint gives you access to an IVR service ๐ฑ When the Call Agent asks, the IVR server will "play" announcements and tones, and it will "listen" to responses from the user, like DTMF input or voice messages. These requests follow the event signaling and reporting procedures defined in MGCP.
+-------------+
| IVR endpoint| -------- Connection
+-------------+
A given IVR endpoint isn't expected to support more than one connection at a time. If several connections were set up to the same endpoint, then the same tones and announcements would be played simultaneously over all of them ๐
2.1.1.5 Conference Bridge Access Point
A conference bridge endpoint is used to provide access to a specific conference ๐
+-------
+--------------------------+|
|Conference bridge endpoint| -------- Connections
+--------------------------+|
+-------
Media gateways should be able to establish several connections between the endpoint and the packet networks, or between the endpoint and other endpoints in the same gateway ๐ The signals from these connections shall be mixed according to the connection "mode," as specified later in this document. The precise number of connections an endpoint supports is a characteristic of the gateway, and it may vary according to how resources are allocated within the gateway.
2.1.1.6 Packet Relay
A packet relay endpoint is a specific form of conference bridge that typically only supports two connections ๐ฆ Packet relays can be found in firewalls between a protected and an open network, or in transcoding servers that provide interoperation between incompatible gateways. For example, those could be gateways that don't support compatible compression algorithms, or gateways that operate over different transmission networks, like IP and ATM ๐
+-------
+---------------------+ |
|Packet relay endpoint| 2 connections
+---------------------+ |
+-------
2.1.1.7 ATM "trunk side" Interface
ATM "trunk side" endpoints typically show up when one or several ATM permanent virtual circuits are used to replace the classic "TDM" trunks that link switches ๐ When ATM/AAL2 is used, several trunks or channels get multiplexed on a single virtual circuit, and each of those trunks corresponds to a single endpoint.
+-------
+------------------+|
(channel) = |ATM trunk endpoint| -------- Connections
+------------------+|
+-------
Media gateways should be able to establish several connections between the endpoint and the packet networks, or between the endpoint and other endpoints in the same gateway ๐ซง The signals from these connections shall be mixed according to the connection "mode," as specified later in this document. The precise number of connections that an endpoint supports is a characteristic of the gateway, and it may vary according to how resources are allocated within the gateway.
2.1.2 Endpoint Identifiers ๐ฆ
Okay bestie, endpoint identifiers are literally the ID card for each endpoint. They have two parts, and both are case-insensitive:
- the domain name of the gateway that's managing the endpoint
- a local name inside that gateway
Endpoint names look like this:
local-endpoint-name@domain-name
The domain-name has to be an absolute domain name as defined in RFC 1034 and includes a host portion. So an example could be:
mygateway.whatever.net
The domain-name can also be an IP address written in the form RFC 821 defines for domain names (see RFC 821 for the details). Another example is:
[192.168.1.2]
IPv4 and IPv6 addresses are both allowed ๐ but honestly, using IP addresses as endpoint identifiers is generally discouraged, so maybe don't ๐
Here's the tea: since the domain name is part of the identifier, different forms or values that point to the same entity are not freely swappable ๐ญ The most recently supplied form and value MUST always be used. No exceptions, no vibes-based swapping.
The local endpoint name is case-insensitive too. Its syntax is hierarchical, so the least specific part is the leftmost term and the most specific part is the rightmost term ๐ง The exact syntax depends on the type of endpoint being named, and it MAY start with a term that identifies the endpoint type. Either way, the local endpoint name MUST follow these naming rules:
- The individual terms of the naming path MUST be separated by a single slash ("/", ASCII 2F hex).
- The individual terms are character strings made of letters, digits or other printable characters. The exceptions are delimiter characters ("/", "@"), wildcard characters ("*", "$") and white spaces.
- Wild-carding is written as an asterisk ("*") or a dollar sign ("$") for each term of the naming path that's being wild-carded. Say the full local endpoint name is:
term1/term2/term3
then the entity name field looks like this, depending on which terms get wild-carded:
*/term2/term3 if term1 is wild-carded
term1/*/term3 if term2 is wild-carded
term1/term2/* if term3 is wild-carded
term1/*/* if term2 and term3 are wild-carded, etc.
In each of these examples, a dollar sign could have shown up instead of an asterisk. โจ
- An asterisk ("*") means: "use ALL values of this term known within the scope of the Media Gateway". Unless specified otherwise, that covers all endpoints configured for service, whatever their actual service state is (in-service or out-of-service).
- A dollar sign ("$") means: "use ANY ONE value of this term known within the scope of the Media Gateway". Unless specified otherwise, that only covers endpoints that are in-service.
Also, it is RECOMMENDED that Call Agents follow these extra rules:
- Wild-carding should only be done from the right. So if a term is wild-carded, all the terms to its right should be wild-carded too.
- When mixed dollar sign and asterisk wild-cards are used, dollar signs should only be used from the right. So if a term has a dollar sign wild-card, all the terms to its right should also have dollar sign wild-cards.
A specific command description can add more selection criteria on top of these general rules. ๐
Also, wild-cards can apply to more than one term, and in that case they shall be evaluated from left to right. Let's say we have the endpoint names "a/1", "a/2", "b/1", and "b/2". Then "$/" (which is not recommended) will evaluate to either "a/1, a/2" or "b/1, b/2". However, "/$" may evaluate to "a/1, b/1", "a/1, b/2", "a/2, b/1", or "a/2, b/2". Using mixed wild-cards in a command is considered error prone and is consequently discouraged. Big "be careful" energy ๐ญ
A local name made of only a wildcard character refers to either all (*) or any ($) endpoints within the media gateway. ๐
2.1.3 Calls and Connections ๐ธ
Connections get created on the Call Agent for every endpoint that's going to be involved in the "call". In the classic example of a connection between two "DS0" endpoints (EP1 and EP2), the Call Agents controlling those endpoints set up two connections (C1 and C2):
+---+ +---+
(channel1) ===|EP1|--(C1)--... ...(C2)--|EP2|===(channel2)
+---+ +---+
Each connection is designated locally by an endpoint-unique connection identifier, and it's characterized by connection attributes. ๐
When the two endpoints live on gateways managed by the same Call Agent, the creation happens in three steps:
- The Call Agent asks the first gateway to "create a connection" on the first endpoint. The gateway allocates resources to that connection and replies with a "session description". The session description holds the info a third party needs to send packets to the new connection, such as the IP address, UDP port and codec parameters.
- The Call Agent then asks the second gateway to "create a connection" on the second endpoint. The command carries the "session description" from the first gateway. The gateway allocates resources to that connection and replies with its own "session description".
- The Call Agent then uses a "modify connection" command to give this second "session description" to the first endpoint. Once that's done, communication can go both ways. ๐ฅ
When the two endpoints are on gateways managed by two different Call Agents, the Call Agents exchange information through a Call-Agent to Call-Agent signaling protocol, e.g., SIP [7], so they can synchronize the creation of the connection on both endpoints. Teamwork makes the dream work ๐ซถ
Once a connection is established, its parameters can be changed at any time with a "modify connection" command. For example, the Call Agent might tell the gateway to change the codec used on a connection, or to change the IP address and UDP port that data gets sent to, if a connection is "redirected". ๐ฆ
The Call Agent removes a connection by sending a "delete connection" command to the gateway. The gateway may also, under some circumstances, inform a gateway that a connection could not be sustained. Awkward, but that's the protocol ๐
Here's the diagram of a connection's states, as seen from the gateway:
Create connection
received
|
V
+-------------------+
|resource allocation|-(failed)-+
+-------------------+ |
| (connection refused)
(successful)
|
v
+----------->+
| |
| +-------------------+
| | remote session |
| | description |----------(yes)--------+
| | available ? | |
| +-------------------+ |
| | |
| (no) |
| | |
| +-----------+ +------+
| +--->| half open |------> Delete <-------| open |<----------+
| | | (wait) | Connection |(wait)| |
| | +-----------+ received +------+ |
| | | | | |
| | Modify Connection | Modify Connection |
| | received | received |
| | | | | |
| | +--------------------+ | +--------------------+ |
| | |assess modification | | |assess modification | |
| | +--------------------+ | +--------------------+ |
| | | | | | | |
| |(failed) (successful) | (failed) (successful) |
| | | | | | | |
| +<---+ | | +-------------+-------+
| | |
+<-------------------+ |
|
+-----------------+
| Free connection |
| resources. |
| Report. |
+-----------------+
|
V
2.1.3.1 Names of Calls ๐
Each connection has an attribute called the "call identifier". As far as the MGCP protocol is concerned, it has little semantic meaning, and it's mainly kept for backwards compatibility. ๐
Calls are identified by unique identifiers that don't depend on the underlying platforms or agents. Call identifiers are hexadecimal strings created by the Call Agent. The maximum length of a call identifier is 32 characters.
Call identifiers are expected to be unique within the system or, at a minimum, unique within the collection of Call Agents that control the same gateways. From the gateway's perspective, the Call identifier is thus unique. When a Call Agent builds several connections that belong to the same call, whether on the same gateway or on different gateways, those connections should share the same call-id. Accounting or management procedures can then use this identifier, and those procedures are outside the scope of MGCP. Not our problem, bestie ๐
2.1.3.2 Names of Connections ๐
Connection identifiers are created by the gateway when it's asked to create a connection. They identify the connection within the context of an endpoint. MGCP treats connection identifiers as hexadecimal strings. The gateway MUST make sure that a proper waiting period, at least 3 minutes, elapses between the end of a connection that used an identifier and that identifier's use in a new connection for the same endpoint (gateways MAY decide to use identifiers that are unique within the context of the gateway). The maximum length of a connection identifier is 32 characters. Don't rush the reuse, slay ๐
2.1.3.3 Management of Resources, Attributes of Connections ๐
okay so bestie, a connection can pick up all kinds of resources, like special signal processing or packetization functions ๐ and they basically fall into two buckets:
- Externally visible resources, which change the format of "the bits on the network" and have to be told to the second endpoint in the connection ๐ฆ
- Internal resources, which decide what signal gets sent over the connection and how the endpoint handles the signals it receives ๐ง
So who decides all this? The gateway does, but only after the Call Agent gives it instructions. The Call Agent sends two sets of parameters to the gateway ๐
- The local directives, which tell the gateway which resources to use for a connection โจ
- When it's available, the "session description" from the other end of the connection (called the remote session description) ๐ซถ
The local directives cover stuff like the connection mode (send-only or send-receive), preferred coding or packetization methods, and whether to use echo cancellation or silence suppression. ๐ (If you want the full list, check the specification of the LocalConnectionOptions parameter of the CreateConnection command.) For each parameter, the Call Agent MAY specify a value, a range of values, or no value at all. This is giving flexibility ๐ญ Some gateways can be super tightly controlled, where the Call Agent spells out every tiny detail of the connection, and others can be super chill, where the Call Agent only says the broad vibes, like the maximum bandwidth, and the gateway picks the rest as long as it stays inside those guidelines ๐
Once the local directives are in, the gateway works out which resources to allocate. When it can, it picks values that line up with the remote session description. But there is no absolute requirement that the parameters match exactly ๐
After the resources are allocated, the gateway writes a "session description" that explains how it plans to send and receive packets. The session description can sometimes offer a range of values. For example, if the gateway can accept several compression algorithms, it can list all of them ๐
Local Directives
(from Call Agent 1)
|
V
+-------------+
| resource |
| allocation |
| (gateway 1) |
+-------------+
| |
V |
Local |
Parameters V
| Session
| Description Local Directives
| | (from Call Agent 2)
| +---> Transmission----+ |
| (CA to CA) | |
| V V
| +-------------+
| | resource |
| | allocation |
| | (gateway 2) |
| +-------------+
| | |
| | V
| | Local
| | Parameters
| Session
| Description
| +---- Transmission<---+
| | (CA to CA)
V V
+-------------+
| modification|
| (gateway 1) |
+-------------+
|
V
Local
Parameters
-- Information flow: local directives & session descriptions --
2.1.3.4 Special Case of Local Connections ๐ธ
big gateways hold a ton of endpoints, and they're often different types ๐ Sometimes, in some networks, we need to set up connections between endpoints that live in the same gateway. Examples are:
- Connecting a call to an Interactive Voice-Response unit ๐
- Connecting a call to a Conferencing unit ๐ค
- Routing a call from one endpoint to another, which people often call a "hairpin" connection ๐
local connections are way easier to set up than network connections ๐ In most cases, they go through some local interconnecting device, like a TDM bus ๐
When two endpoints sit under the same gateway, you can set up the connection in one single command that names both endpoints. It's basically a "Create Connection" command that puts the name of the second endpoint where the "remote session description" would normally go ๐
2.1.4 Names of Call Agents and Other Entities ๐
MGCP was built so you can run redundant Call Agents for better network reliability ๐ก๏ธ That means there's no fixed link between entities and hardware platforms or network interfaces ๐ฆ
Call Agent names have two parts, just like endpoint names. The local part has no internal structure, semantically speaking. Here's an example Call Agent name:
ca1@ca.whatever.net
Both the local part and the domain name have to be supplied. Still, implementations are encouraged to accept Call Agent names that only have the domain name ๐ซถ
Here's how you make reliability better ๐
- Entities like endpoints or Call Agents are identified by their domain name, not their network addresses. A domain name can be tied to several addresses. If a command or response can't reach one of those network addresses, implementations MUST retry the transmission using another address ๐
- Entities MAY move to another platform. The link between a logical name (the domain name) and the actual platform lives in the domain name service. Call Agents and Gateways MUST keep track of the time-to-live of the records they read from the DNS. They MUST query the DNS to refresh the information once the time to live has expired โฐ
On top of the domain name indirection and the DNS, the "notified entity" is the key to reliability and fail-over in MGCP ๐ Each endpoint has a "notified entity," which is the Call Agent currently controlling it. At any moment, an endpoint has one, and only one, "notified entity." The "notified entity" decides where the endpoint sends its commands. When the endpoint needs to send a command to the Call Agent, it MUST send the command to its current "notified entity" ๐ฎ But the "notified entity" doesn't decide where commands can come from. Any Call Agent can send commands to the endpoint ๐ Please refer to Section 5 for the relevant security considerations ๐
When an endpoint starts up, the "notified entity" MUST be set to a provisioned value ๐ Most commands from the Call Agent can name the "notified entity" explicitly with a NotifiedEntity parameter. The "notified entity" stays the same until either a new NotifiedEntity parameter arrives or the endpoint does a warm or cold (power-cycle) restart ๐
If a NotifiedEntity parameter is sent with an "empty" value, the endpoint's "notified entity" is set to empty too. If the "notified entity" is empty or was never set explicitly (neither by a command nor by provisioning), it defaults to the source address (IP address and UDP port number) of the last successful non-audit command the endpoint received. So auditing won't change the "notified entity" ๐ Using an empty NotifiedEntity parameter value is strongly discouraged. It's error prone and it kills the DNS-based fail-over and reliability mechanisms ๐
2.1.5 Digit Maps ๐
okay so the Call Agent can ask the gateway to collect the digits a user dials ๐ This is mainly for residential gateways, where it grabs the numbers someone punches in. It's also useful on trunking gateways and access gateways, for access codes, credit card numbers, and other numbers that call control services ask for ๐ข
One way to do it is for the gateway to tell the Call Agent about every single digit the moment it's dialed. ngl that's a LOT of back-and-forth ๐ญ It's way better to stash the dialed numbers in a buffer and send them all in one message ๐
The catch is that it's hard for the gateway to know how many digits to collect before sending them ๐ For example, here's what you can dial on the phone at our desk:
------------------------------------------------------
| 0 | Local operator |
| 00 | Long distance operator |
| xxxx | Local extension number |
| 8xxxxxxx | Local number |
| #xxxxxxx | Shortcut to local number at|
| | other corporate sites |
| *xx | Star services |
| 91xxxxxxxxxx | Long distance number |
| 9011 + up to 15 digits| International number |
------------------------------------------------------
The fix is for the Call Agent to load the gateway with a digit map that matches the dial plan ๐ฆ This digit map uses a syntax borrowed from the Unix command egrep, which is very giving old-school vibes โจ So the dial plan above becomes this digit map:
(0T|00T|[1-7]xxx|8xxxxxxx|#xxxxxxx|*xx|91xxxxxxxxxx|9011x.T)
The formal syntax for the digit map is the DigitMap rule in the protocol's formal syntax description (see Appendix A). Support for the basic digit map letters is REQUIRED, while support for the extension digit map letters is OPTIONAL ๐ง If a gateway gets a digit map using an extension letter it doesn't support, it SHOULD return error code 537 (unknown digit map extension).
A digit map is either a (case insensitive) "string" or a list of strings ๐ Each string in the list is its own numbering scheme. It can be a set of digits or timers, or an expression that the gateway tries to shortest-match against. Each numbering scheme can use these constructs:
- Digit: A digit from "0" to "9".
- Timer: The symbol "T", which matches a timer expiry.
- DTMF: A digit, a timer, or one of the symbols "A", "B", "C", "D", "#", or "*". Extensions may be defined.
- Wildcard: The symbol "x", which matches any digit ("0" to "9").
- Range: One or more DTMF symbols enclosed in square brackets ("[" and "]").
- Subrange: Two digits separated by a hyphen ("-"), which matches any digit between them, inclusive. Subranges can only be used inside a range, i.e., between "[" and "]".
- Position: A period ("."), which matches an arbitrary number, including zero, of occurrences of the construct right before it.
A gateway that detects events to be matched against a digit map MUST do the following:
- Add the event code as a token to the end of an internal state variable for the endpoint called the "current dial string".
- Apply the current dial string to the digit map table, trying to match each expression in the digit map.
- If the result is under-qualified (it partially matches at least one entry in the digit map and doesn't completely match another entry), do nothing further.
If the result matches an entry, or it's over-qualified (meaning no further digits could possibly produce a match), send the list of accumulated events to the Call Agent ๐ค In this spec, a match is either a "perfect match," which exactly matches one of the alternatives, or an impossible match, which happens when the dial string doesn't match any alternative. Unexpected timers, for example, can cause "impossible matches" ๐ Both perfect matches and impossible matches trigger notification of the accumulated digits (which may include other events - see Section 2.3.3).
Here's an example. Say we have the digit map:
(xxxxxxx|x11)
and a current dial string of "41". If the input is "1", the current dial string becomes "411". That's a partial match with "xxxxxxx" but a complete match with "x11", so we send "411" to the Call Agent ๐
This next digit map example is more subtle ๐
(0[12].|00|1[12].1|2x.#)
If the input is "0", there's an immediate match, since the position (".") allows for zero occurrences of the construct before it. That means "00" can never actually be produced by this digit map ๐
If the input is "1", it's only a partial match. "12" is also only a partial match, but both "11" and "121" are matches ๐ธ
If the input is "2", it's a partial match. "23", "234", "2345", and so on are also partial matches. A full match doesn't happen until a "#" is generated, e.g., "2345#". The input "2#" would also have been a match ๐
Digit maps are really just a way to match sequences of event codes against a grammar ๐ง Even though digit maps as defined here are for DTMF input, extension packages can define digit maps for other kinds of input that are represented by event codes following the digit map syntax already defined for them (e.g., "1" or "T"). When that's the plan, the definition of the particular event(s) SHOULD explicitly state it in the package definition.
Since digit maps aren't bounded in size, it is RECOMMENDED that gateways support digit maps up to at least 2048 bytes per endpoint ๐ซถ
2.1.6 Packages ๐
MGCP is modular and extensible, but extensibility means you need a way to manage, identify, and name each extension ๐ That's where packages come in. A package is just a well-defined grouping of extensions. For example, one package might cover a group of events and signals, like off-hook and ringing, for analog access lines. Another package might cover a different group for analog access lines or for another endpoint type, like video ๐น A given endpoint can support one or more packages.
MGCP lets a package define these types of extensions:
- BearerInformation
- LocalConnectionOptions
- ExtensionParameters
- ConnectionModes
- Events
- Signals
- Actions
- DigitMapLetters
- ConnectionParameters
- RestartMethods
- ReasonCodes
- Return codes
We'll go through each of these in more detail below โจ The rules for defining each extension in a package are in Section 6, and the encoding and syntax are in Section 3 and Appendix A.
Except for DigitMapLetters, a package gets its own namespace for each type of extension by putting the package name in front of the extension name, like this:
package-name/extension
So the package name is followed by a slash ("/") and then the extension name ๐
An endpoint that supports one or more packages can pick one of them as its default package. Using the package name for events and signals in the endpoint's default package is OPTIONAL, but it is RECOMMENDED to always include the package name anyway ๐ Every other extension in the package, except DigitMapLetter, MUST include the package name when it's referred to.
Package names are case insensitive strings made of letters, hyphens, and digits, with one rule: hyphens shall never be the first or last character in a name ๐ฆ Examples are "D", "T", and "XYZ". Case doesn't matter, so names like XYZ, xyz, and xYz are all equal.
Package definitions are provided in other documents, and the package names and extension names are registered with IANA. For more details, check section 6 ๐
Implementers can get experience by using experimental packages. The name of an experimental package MUST start with the two characters "x-". IANA SHALL NOT register package names starting with these characters, or with the characters "x+", which are reserved ๐งช A gateway that gets a command referring to a package it doesn't support MUST return an error (error code 518 - unsupported package, is RECOMMENDED) ๐
2.1.7 Events and Signals โจ
Okay bestie, events and signals are literally the heart of MGCP ๐ A Call Agent can ask to be notified when something happens on an endpoint, like an off-hook event ๐, by putting the event name in a RequestedEvents parameter inside a NotificationRequest command (see Section 2.3.3) ๐
A Call Agent can also ask for a signal to be applied to an endpoint, like dial-tone ๐ถ, by putting its name in a SignalRequests parameter ๐
Events and signals live in packages, and inside a package they share one name space. From here on we'll just call those event names ๐ง Event names are case insensitive strings of letters, hyphens and digits, and hyphens SHALL NOT be the first or last character in a name ๐ Some events need extra data, which goes in parentheses ๐ธ Event names are not case sensitive, so "hu", "Hu", "HU" and "hU" are all equal ๐
Examples of event names are "hu" (off hook or "hang-up" transition), "hf" (hook-flash) and "0" (the digit zero) ๐
The package name is OPTIONAL for events in the default package for an endpoint, but it's RECOMMENDED to always include it ๐ซถ If the package name is left off, the default package name for that endpoint MUST be assumed. For example, an analog access line has the line package ("L") as its default, and dial-tone ("dl") is one of the events in that package. So these two event names are equal:
L/dl
and
dl
For any other non-default packages associated with that endpoint (like the generic package for an analog access endpoint-type), the package name MUST be included with the event name. Again, unconditional inclusion of the package name is RECOMMENDED ๐
Digits, or letters, are supported in some packages, notably "DTMF" ๐น Digits and letters are defined by the rules "Digit" and "Letter" in the definition of digit maps. This covers the digits (0 to 9), the asterisk or star ("*"), the orthotrope, number or pound sign ("#"), the letters "A", "B", "C" and "D", and the timer indication "T". These can be combined into a "digit string" that represents the keys a user punched on a dial. The letter "X" can also be used to represent all digits (0 to 9). Extensions MAY define use of other letters too ๐ฆ
Because earlier versions of the protocol needed to express digit strings easily, there's a consequence for event names. Here's the rule, and it's a big one ๐
An event name that does not denote a digit MUST always contain at least one character that is neither a digit, nor one of the letters A, B, C, D, T or X (such names also MUST NOT just contain the special signs "*", or "#"). Event names consisting of more than one character however may use any of the above.
A Call Agent often has to ask a gateway to detect a group of events ๐ต๏ธโโ๏ธ There are two conventions for denoting such groups:
- The "*" and "all" wildcard conventions (see below) can detect any event belonging to a package, a given event in many packages, or any event in any package supported by the gateway.
- The regular expression Range notation can detect a range of digits.
The star sign (*) can be used as a wildcard instead of a package name, and the keyword "all" can be used as a wildcard instead of an event name ๐ซ
- A name such as "foo/all" denotes all events in package "foo".
- A name such as "*/bar" denotes the event "bar" in any package supported by the gateway.
- The name "*/all" denotes all events supported by the endpoint.
This specification purposely does not define any additional detail for the "all packages" and "all events" wildcards. They provide limited benefits, but introduce significant complexity along with the potential for errors. Their use is consequently strongly discouraged ๐ โโ๏ธ
The Call Agent can ask a gateway to detect a set of digits or letters either by individually describing those letters, or by using the "range" notation defined in the syntax of digit strings. For example, the Call Agent can:
- Use the letter "x" to denote digits from 0 to 9.
- Use the notation "[0-9#]" to denote the digits 0 to 9 and the pound sign.
The individual event codes are still defined in a package though (e.g., the "DTMF" package) ๐
Events can by default only be generated and detected on endpoints. But events can also be defined so they can be generated or detected on connections rather than on the endpoint itself (see Section 6.6) ๐ง For example, gateways may be asked to provide a ringback tone on a connection. When an event is to be applied on a connection, the name of the connection MUST be added to the name of the event, using an "at" sign (@) as a delimiter, like this:
G/rt@0A3F58
Here "G" is the name of the package and "rt" is the name of the event. If the connection gets deleted while an event or signal is being detected or applied on it, that particular event detection or signal generation simply stops. Depending on the signal, this may generate a failure (see below) ๐ฌ
The wildcard character "*" (star) can be used to denote "all connections" ๐ When this convention is used, the gateway will generate or detect the event on all the connections that are connected to the endpoint. This applies to existing connections as well as future ones created on the endpoint. An example:
R/qa@*
Here "R" is the name of the package and "qa" is the name of the event.
When processing a command using the "all connections" wildcard, the "" wildcard character applies to all current and future connections on the endpoint, but it will not be expanded. If a subsequent command either explicitly (e.g., by auditing) or implicitly (e.g., by persistence) refers to such an event, the "" value will be used. However, when the event is actually observed, that particular occurrence of the event will include the name of the specific connection it occurred on ๐
The wildcard character "$" can be used to denote "the current connection" ๐ท It can only be used by the Call Agent, and only when the event notification request is "encapsulated" within a connection creation or modification command. When this convention is used, the gateway will generate or detect the event on the connection that is currently being created or modified. An example:
G/rt@$
When processing a command using the "current connection" wildcard, the "$" wildcard character will be expanded to the value of the current connection. If a subsequent command either explicitly (e.g., by auditing) or implicitly (e.g., by persistence) refers to such an event, the expanded value will be used. In other words, the "current connection" wildcard is expanded once, at the initial processing of the command in which it was explicitly included ๐ฅ
The connection id, or a wildcard replacement, can be used together with the "all packages" and "all events" conventions. For example:
*/all@*
can be used to designate all events on all current and future connections on the endpoint. But, as mentioned before, the use of the "all packages" and "all events" wildcards is strongly discouraged ๐
Signals are divided into different types depending on their behavior ๐ญ
- On/off (OO): Once applied, these signals last until they are turned off. This can only happen as the result of a reboot/restart, or a new SignalRequests where the signal is explicitly turned off (see later). Signals of type OO are defined to be idempotent, so multiple requests to turn a given OO signal on (or off) are perfectly valid and MUST NOT result in any errors. An On/Off signal could be a visual message-waiting indicator (VMWI). Once turned on, it MUST NOT be turned off until explicitly instructed to by the Call Agent, or as a result of an endpoint restart. In other words, these signals will not turn off just because a requested event was detected ๐ก
- Time-out (TO): Once applied, these signals last until they are either cancelled (by the occurrence of an event, or by not being included in a subsequent, possibly empty, list of signals), or until a signal-specific period of time has elapsed. A TO signal that times out will generate an "operation complete" event. A TO signal could be "ringback" timing out after 180 seconds โฒ๏ธ If an event occurs prior to the 180 seconds, the signal will, by default, be stopped (the "Keep signals active" action, see Section 2.3.3, will override this behavior). If the signal is not stopped, it will time out, stop and generate an "operation complete" event, which the Call Agent may or may not have requested to be notified about. If the Call Agent has asked for the "operation complete" event to be notified, the "operation complete" event sent to the Call Agent SHALL include the name(s) of the signal(s) that timed out (note that if parameters were passed to the signal, the parameters will not be reported). If the signal was generated on a connection, the name of the connection SHALL be included as described above. Time-out signals have a default time-out value defined for them, which MAY be altered by the provisioning process. Also, the time-out period may be provided as a parameter to the signal (see Section 3.2.2.4). A value of zero indicates that the time-out period is infinite. A TO signal that fails after being started, but before having generated an "operation complete" event, will generate an "operation failure" event which will include the name of the signal that failed. Deletion of a connection with an active TO signal will result in such a failure ๐ซ
- Brief (BR): The duration of these signals is normally so short that they stop on their own. If a signal stopping event occurs, or a new SignalRequests is applied, a currently active BR signal will not stop. However, any pending BR signals not yet applied MUST be cancelled. (A BR signal becomes pending if a NotificationRequest includes a BR signal and there is already an active BR signal.) As an example, a brief tone could be a DTMF digit. If the DTMF digit "1" is currently being played and a signal stopping event occurs, the "1" would play to completion. If a request to play DTMF digit "2" arrives before DTMF digit "1" finishes playing, DTMF digit "2" would become pending ๐ต
Signal(s) generated on a connection MUST include the name of that connection ๐ฉท
2.2 Usage of SDP ๐
The Call Agent uses MGCP to give the endpoint a description of connection parameters, like IP addresses, UDP port and RTP profiles ๐ฐ๏ธ These descriptions follow the conventions laid out in the Session Description Protocol, which is now an IETF proposed standard, documented in RFC 2327 ๐
2.3 Gateway Control Commands ๐
2.3.1. Overview of Commands โจ
Okay bestie, let's talk commands ๐ MGCP has nine of them, split into two squads: connection handling and endpoint handling ๐. Here's the lineup:
- The Call Agent can issue an EndpointConfiguration command to a gateway, telling the gateway which coding characteristics the "line-side" of the endpoint expects ๐ฆ
- The Call Agent can issue a NotificationRequest command to a gateway, asking it to watch for specific events like hook actions or DTMF tones on an endpoint ๐
- The gateway will then use the Notify command to tell the Call Agent when those requested events happen ๐
- The Call Agent can use the CreateConnection command to create a connection that terminates in an "endpoint" inside the gateway ๐ธ
- The Call Agent can use the ModifyConnection command to change the parameters of a connection that already exists ๐ง
- The Call Agent can use the DeleteConnection command to delete an existing connection. The gateway can also use DeleteConnection to say a connection can no longer be sustained ๐
- The Call Agent can use the AuditEndpoint and AuditConnection commands to audit the status of an "endpoint" and any connections attached to it. Anything beyond these commands is generally desirable for network management, and that's expected to come from SNMP and a MIB, which is outside the scope of this spec ๐ง
- The Gateway can use the RestartInProgress command to tell the Call Agent that a group of endpoints it manages is being taken out-of-service or placed back in-service ๐
These services let a controller (normally, the Call Agent) tell a gateway to create connections that terminate in an "endpoint" attached to that gateway, and keep the controller informed about events happening at the endpoint โจ An endpoint could be, for example:
- A specific trunk circuit, within a trunk group terminating in a gateway,
- A specific announcement handled by an announcement server.
Connections get grouped into "calls" (though honestly, the concept of a "call" has little semantic meaning in MGCP itself, so don't overthink it ๐). Several connections, which may or may not belong to the same call, can terminate in the same endpoint. Each connection is qualified by a "mode" parameter ๐ฆ, and it can be set to "send only" (sendonly), "receive only" (recvonly), "send/receive" (sendrecv), "conference" (confrnce), "inactive" (inactive), "loopback", "continuity test" (conttest), "network loop back" (netwloop) or "network continuity test" (netwtest) ๐
Media generated by the endpoint gets sent on connections whose mode is "send only", "send/receive", or "conference", unless the endpoint has a connection in "loopback" or "continuity test" mode. BUT, media generated by applying a signal to a connection is always sent on that connection, no matter what the mode is ๐ซถ
Now for incoming media. How it's handled depends on the mode parameters:
- Media streams received through connections in "receive", "conference" or "send/receive" mode get mixed and sent to the endpoint, unless the endpoint has another connection in "loopback" or "continuity test" mode ๐ง
- Media streams originating from the endpoint are transmitted over all the connections whose mode is "send", "conference" or "send/receive", unless the endpoint has another connection in "loopback" or "continuity test" mode ๐ก
- Besides being sent to the endpoint, a media stream received through a connection in "conference" mode is forwarded to all the other connections whose mode is "conference". This still happens when the endpoint has a connection in "loopback" or "continuity test" mode. How that forwarding works, like whether it's an RTP translator or a mixer, is outside the scope of this document ๐
Heads up on events: to detect events on a connection, the connection must by default be in one of the modes "receive", "conference", "send/receive", "network loopback" or "network continuity test". Event detection only applies to incoming media. Connections in "sendonly", "inactive", "loopback", or "continuity test" mode will normally not detect any events, although asking them to isn't considered an error ๐
The "loopback" and "continuity test" modes are for maintenance and continuity test operations ๐ An endpoint may have more than one connection in either "loopback" or "continuity test" mode. As long as there's at least one connection in that particular mode, and no other connection on the endpoint is in a different maintenance or test mode, the maintenance or test operation shall continue undisturbed ๐
There are two flavors of continuity test: one specified by ITU and one used in the US.
In the ITU version, the test is a loopback test. The originating switch sends a tone (the go tone) on the bearer circuit and expects the terminating switch to loop the tone back. If the originating switch sees that same tone come back (the return tone), the COT has passed. If not, the COT has failed.
In the US version, the go and return tones are different. The originating switch sends a certain go tone. The terminating switch detects the go tone and asserts a different return tone in the backwards direction. When the originating switch detects the return tone, the COT is passed. If the originating switch never detects the return tone, the COT has failed ๐
Here's how the modes play out in practice:
- If the mode is set to "loopback", the gateway is expected to return the incoming signal from the endpoint back into that same endpoint. This is typically used for testing the continuity of trunk circuits according to the ITU specifications ๐
- If the mode is set to "continuity test", the gateway is informed that the other end of the circuit has started a continuity test procedure according to the GR specification (see [22]). The gateway will then place the circuit in the transponder mode required for dual-tone continuity tests ๐งช
- If the mode is set to "network loopback", the audio signals received from the connection get echoed back on that same connection. The media is not forwarded to the endpoint ๐ฆ
- If the mode is set to "network continuity test", the gateway processes the packets received from the connection according to the transponder mode required for dual-tone continuity test, then sends the processed signal back on the connection. The media is not forwarded to the endpoint. Heads up: the "network continuity test" mode is only included for backwards compatibility, and using it is discouraged ๐ โโ๏ธ
2.3.2. EndpointConfiguration โจ
Okay, EndpointConfiguration is the command for telling the endpoint how the signals it receives are encoded ๐ง For example, in some international telephony setups, certain calls carry mu-law encoded audio while others use A-law. The Call Agent uses EndpointConfiguration to pass this info to the gateway. The configuration can vary from call to call, but it can also be used when there's no connection at all ๐
ReturnCode,
[PackageList]
<-- EndpointConfiguration(EndpointId,
[BearerInformation])
EndpointId is the name of the endpoint(s) in the gateway where EndpointConfiguration runs. The "any of" wildcard convention MUST NOT be used. If the "all of" wildcard convention is used, the command applies to all the endpoints whose name matches the wildcard ๐ธ
Quick heads up: the "any of" wildcard is a no-go here, but "all of" is fine, and it hits every endpoint whose name matches. Don't mix those up, bestie ๐
BearerInformation is a parameter that defines the coding of the data sent to and received from the line side. It's encoded as a list of sub-parameters. The only sub-parameter defined in this version of the spec is the bearer encoding, whose value can be A-law or mu-law. The set of sub-parameters may be extended later ๐ฆ
To allow for extensibility while staying backwards compatible, BearerInformation is conditionally optional, based on these conditions:
- if Extension Parameters (vendor, package or other) are not used, the BearerInformation parameter is REQUIRED,
- otherwise, the BearerInformation parameter is OPTIONAL.
When it's omitted, BearerInformation MUST retain its current value ๐
ReturnCode is a parameter returned by the gateway. It shows the outcome of the command and consists of an integer number, optionally followed by commentary ๐
PackageList is a list of supported packages that MAY be included with error code 518 (unsupported package) โจ
2.3.3. NotificationRequest โจ
NotificationRequest is how the Call Agent asks the gateway to send notifications when specified events happen on an endpoint ๐ For example, you could request a notification when the gateway detects that an endpoint is receiving tones associated with fax communication. The entity that receives this notification might then decide to use a different encoding method on the connections bound to that endpoint, and tell the gateway with a ModifyConnection Command ๐
ReturnCode,
[PackageList]
<-- NotificationRequest(EndpointId,
[NotifiedEntity,]
[RequestedEvents,]
RequestIdentifier,
[DigitMap,]
[SignalRequests,]
[QuarantineHandling,]
[DetectEvents,]
[encapsulated EndpointConfiguration])
EndpointId is the identifier for the endpoint(s) in the gateway where NotificationRequest runs. The "any of" wildcard MUST NOT be used ๐ซ
NotifiedEntity is an optional parameter that specifies a new "notified entity" for the endpoint ๐ง
RequestIdentifier is used to match this request up with the notifications it triggers. It gets repeated in the corresponding Notify command ๐
RequestedEvents is a list of events, possibly qualified by event parameters (see Section 3.2.2.4), that the gateway is asked to detect and report. These events could include things like fax tones, continuity tones, or on-hook transitions. Unless otherwise specified, events are detected on the endpoint, but some events can be detected on a connection instead ๐ A given event MUST NOT appear more than once in a RequestedEvents. If the parameter is omitted, it defaults to empty ๐
Each event has one or more associated actions, which can be:
- Notify the event immediately, together with the accumulated list of observed events,
- Swap audio,
- Accumulate the event in an event buffer, but don't notify yet,
- Accumulate according to Digit Map,
- Keep Signal(s) active,
- Process the Embedded Notification Request,
- Ignore the event.
Support for Notify, Accumulate, Keep Signal(s) Active, Embedded Notification Request, and Ignore is REQUIRED. Support for Accumulate according to Digit Map is REQUIRED on any endpoint capable of detecting DTMF. Support for any other action is OPTIONAL. The set of actions can be extended ๐
okay so a given action can technically be set for any event ๐ but some actions just won't make sense for certain events. like, an off-hook event with the Accumulate according to Digit Map action is valid, but it will immediately trigger a digit map mismatch the second the off-hook happens ๐ so yeah, that's a whole vibe we don't want. it's discouraged, bestie ๐
these are the combos that work together, where "Y" means yes they can be combined and "N" means nope ๐ซ:
--------------------------------------------------------------
| | Notif | Swap | Accum | AccDi | KeSiA | EmbNo | Ignor |
|--------------------------------------------------------------|
| Notif | N | Y | N | N | Y | Y* | N |
| Swap | - | N | Y | N | N | N | Y |
| Accum | - | - | N | N | Y | Y | N |
| AccDi | - | - | - | N | Y | N | N |
| KeSiA | - | - | - | - | N | Y | Y |
| EmbNo | - | - | - | - | - | N | N |
| Ignor | - | - | - | - | - | - | N |
--------------------------------------------------------------
the Y* one has a little asterisk footnote, so read this next bit carefully ๐ โญ
Note (*): the "Embedded Notification Request" can only be combined with "Notify" if the gateway is allowed to issue more than one Notify command per Notification request (see below and Section 4.4.1). the vibe is basically that it depends on what the gateway is allowed to do ๐ซถ
okay, so if no action is specified at all, the Notify action gets applied by default ๐ฆ. if one or more actions are specified, then only those actions apply, and nothing else sneaks in. when you stack two or more actions, each one MUST be combinable with all the other actions according to the table above, because the individual actions are assumed to happen simultaneously โจ. no cap, that's the rule.
now if a client gets a request with an invalid or unsupported action, or an illegal combination of actions, it MUST return an error to the Call Agent. the error code is 523 (unknown or illegal combination of actions), and that one is RECOMMENDED ๐
next up: "persistent events" ๐ง. in addition to the RequestedEvents parameter in the command, some MGCP packages may contain persistent events (this is generally discouraged though, so check out Appendix B for an alternative ๐ ). persistent events in a given package are always detected on an endpoint that implements that package. so if a persistent event is not in the RequestedEvents list and it happens anyway, it still gets detected and processed like everything else, as if it had been requested with a Notify action. the catch is that a NotificationRequest MUST still be in place for a persistent event to trigger a Notify ๐. so informally, persistent events are kinda always implicitly in the RequestedEvents list with a Notify action, except no glare detection (or anything like that) gets performed ๐
non-persistent events are the ones that have to be explicitly listed in RequestedEvents ๐ธ. the (possibly empty) list you send completely replaces the previous list of requested events. besides the persistent events, only the events in the requested list get detected by the endpoint. and if a persistent event is in RequestedEvents, the action you specify replaces the default action for that event for the life of that RequestedEvents list. after that, the default action comes back ๐. for example: say "off-hook" was a persistent event, you specified the "Ignore off-hook" action, and then a new request came in with no off-hook instructions at all. the default "Notify off-hook" operation would be restored ๐
the gateway detects the union of the persistent events and the requested events. if an event isn't in either list, it gets ignored ๐
the Call Agent can send a NotificationRequest with an empty (or omitted) RequestedEvents list to the gateway โจ. for example, it can do that when it doesn't want to collect any more DTMF digits anymore ๐ โโ๏ธ. persistent events will still be detected and notified though, so don't forget about them ๐ซถ
now the Swap Audio action ๐ฆ. this one can be used when a gateway handles more than one connection on an endpoint. that's gonna be the case for call waiting, and possibly other feature scenarios too. to avoid the round trip to the Call Agent just to change which connection is attached to the audio functions of the endpoint, the NotificationRequest can map an event (usually hook flash, but it could be some other event) to a local swap audio function. that function selects the "next" connection in a round robin fashion ๐. if there's only one connection, the action is effectively a no-op ๐ด. if there are more than two connections, the order is undefined ๐คทโโ๏ธ. and if the endpoint has exactly two connections, one of which is "inactive" and the other in "send/receive" mode, then swap audio will attempt to make the "send/receive" connection "inactive", and vice versa ๐. this specification intentionally doesn't say any more about the swap audio action, so that's all you get ๐
if you want signal(s) to start when the event you're looking for occurs, you can use the "Embedded NotificationRequest" action ๐. the embedded NotificationRequest can include a new list of RequestedEvents, SignalRequests, and a new digit map as well. its semantics are as if a brand new NotificationRequest was just received with the same NotifiedEntity, RequestIdentifier, QuarantineHandling, and DetectEvents โจ. when the Embedded NotificationRequest is activated, the "current dial string" gets cleared. however, the list of observed events and the quarantine buffer stay unaffected (if it's combined with a Notify, the Notify will clear the list of observed events though, see Section 4.4.1 ๐). note that the Embedded NotificationRequest action does not accumulate the triggering event by itself, but it can be combined with the Accumulate action to get that done ๐ง. and if the Embedded NotificationRequest fails, an Embedded NotificationRequest failure event SHOULD be generated (see Appendix B) ๐จ
MGCP implementations SHALL be able to support at least one level of embedding ๐ช. an embedded NotificationRequest that respects this limitation MUST NOT contain another Embedded NotificationRequest ๐ โโ๏ธ. so no nested embedding inception, periodt ๐ญ
DigitMap is an optional parameter that lets the Call Agent provision the endpoint with a digit map, and digits get accumulated according to that map ๐ข. if this optional parameter is absent, the previously defined value is retained ๐ซถ. this parameter MUST be defined, either explicitly or through a previous command, if the RequestedEvents parameter has a request to "accumulate according to the digit map" ๐. the collected digits end up as a digit string. the digit string is set to a null string when the NotificationRequest comes in, so any later notification only returns the digits collected after that request โจ. digits accumulated according to the digit map get reported like any other accumulated event, in the order they happened. so it's totally possible for other accumulated events to show up in between the digits ๐ธ. and if the gateway is asked to "accumulate according to digit map" but it doesn't currently have a digit map for that endpoint, the gateway MUST return an error (error code 519, endpoint does not have a digit map, which is RECOMMENDED) ๐ซ
SignalRequests is an optional parameter with the set of signals the gateway is asked to apply ๐. when it's omitted, it defaults to empty. when multiple signals are specified, the signals MUST be applied in parallel ๐ถ. unless otherwise specified, signals get applied to the endpoint, but some signals can be applied to a connection instead ๐ฆ. signals are identified by their name (which is an event name), and they can be qualified by signal parameters (see Section 3.2.2.4) ๐ . here are some examples of signals:
- Ringing
- Busy tone
- Call waiting tone
- Off hook warning tone
- Ringback tones on a connection
names and descriptions of signals are defined in the appropriate package ๐ฆ
signals are, by default, applied to endpoints ๐ . if a signal applied to an endpoint results in a media stream (audio, video, etc.) being generated, then by default that media stream MUST NOT be forwarded on any connection associated with that endpoint, regardless of the mode of the connection ๐ค. for example, if a call-waiting tone is applied to an endpoint that's in an active call, only the party using that endpoint will hear the call-waiting tone ๐. however, individual signals may define a different behavior, so keep an eye out โญ
when a signal is applied to a connection that has received a RemoteConnectionDescriptor, the media stream generated by that signal gets forwarded on the connection no matter the current mode of the connection (including loopback and continuity test) ๐. if a RemoteConnectionDescriptor has not been received, the gateway MUST return an error (error code 527, missing RemoteConnectionDescriptor, which is RECOMMENDED) ๐ฌ. also, this restriction doesn't apply to detecting events on a connection, so only the signal part is affected ๐
when a (possibly empty) list of signal(s) is supplied, that list completely replaces the current list of active time-out signals ๐ฐ๏ธ. any currently active time-out signals that are not in the new list MUST be stopped, and the new signal(s) provided will now become active ๐. any currently active time-out signals that are in the new list MUST remain active without interruption, so their timer doesn't get affected at all โฑ๏ธ. which means there's currently no way to restart the timer for an active time-out signal without turning it off first ๐. if the time-out signal is parameterized, the original set of parameters MUST remain in effect, no matter what values come in later ๐. and a given signal MUST NOT appear more than once in a SignalRequests ๐ซ. last but not least, applying a signal S to an endpoint, connection C1, and connection C2 counts as three different and independent signals ๐งโโ๏ธโจ
The action triggered by the SignalRequests is synced up with the events in the RequestedEvents parameter ๐. Say the NotificationRequest says "ringing" and RequestedEvents is looking for an "off-hook" event. Then the ringing SHALL stop the second the gateway detects that off-hook ๐. The formal version is that the generation of all "Time Out" signals SHALL stop as soon as one of the requested events is detected, unless the "Keep signals active" action is associated to the detected event ๐
. RequestedEvents and SignalRequests can point at the same event definitions. The difference is that RequestedEvents asks the gateway to detect the event, while SignalRequests asks it to generate one ๐ฆ. Which events and signals an endpoint can detect or perform depends on the packages that endpoint supports, and each package lists its own events and signals โจ. If a gateway is asked to detect or perform an event from a package the endpoint doesn't support, it MUST return an error (error code 518 - unsupported or unknown package, is RECOMMENDED) ๐. If the event name has no package name attached, the endpoint's default package is assumed. If the event isn't registered in that default package, the gateway MUST return an error (error code 522 - no such event or signal, is RECOMMENDED) ๐.
The Call Agent can send a NotificationRequest with an empty requested signal list. It does this, for example, when a time-out signal(s) should stop ๐ธ.
If you want signal(s) to start the moment a "looked-for" event happens, use the "Embedded NotificationRequest" action ๐ง. The embedded NotificationRequest can bring its own new RequestedEvents, SignalRequests and Digit Map. It basically lets the Call Agent set up a "mini-script" that the gateway runs right after the associated event is detected ๐ฅ. Any SignalRequests in the embedded NotificationRequest start immediately. Care is needed to avoid discrepancies between the Call Agent and the gateway ๐. Long-term discrepancies shouldn't stick around, though, because a new SignalRequests completely replaces the old list of active time-out signals, and BR-type signals always stop on their own ๐ซถ. Keeping the number of On/Off-type signals low is encouraged. It's also considered good practice for a Call Agent to now and then turn on every On/Off signal that should be on, and turn off every On/Off signal that should be off โจ.
The Ignore action lets you ignore an event, for example to stop a persistent event from being notified ๐. Even so, a time-out signal still syncs up with the event by default. A time-out dial-tone signal will stop when off-hook happens, even if off-hook was a requested event with the "Ignore" action. To stop that sync, you also have to specify the "Keep Signal(s) Active" action ๐ .
The optional QuarantineHandling parameter controls how "quarantine" events are handled. Those are events the gateway detected before this NotificationRequest arrived, but that haven't been notified to the Call Agent yet ๐ฆ. The parameter has a few handling options (see Section 4.4.1 for details):
- whether the quarantined events should be processed or discarded (the default is to process them).
- whether the gateway is expected to generate at most one notification (step by step), or multiple notifications (loop), in response to this request (the default is at most one).
If the parameter is absent, the default value is assumed ๐.
Also note that the quarantine-handling parameter covers events that were detected and processed but not yet notified when the command arrives ๐.
DetectEvents is an optional parameter, possibly qualified by event parameters. It lists the events the gateway should detect during the quarantine period ๐. If DetectEvents is absent, the quarantine-period events are the ones in the last DetectEvents list that was received. On top of that, the gateway will also detect persistent events and the events in the RequestedEvents list, including the ones with the "ignore" action specified ๐.
Some events and signals, like the in-line ringback or the quality alert, happen on connections that terminate in the endpoint, not on the endpoint itself ๐ฆ. The structure of the event names (see Section 2.1.7) lets the Call Agent pick which connection(s) the events should be performed or detected on ๐.
The NotificationRequest command can carry an encapsulated EndpointConfiguration command, which applies to the same endpoint(s) โจ. When it's there, the EndpointConfiguration parameters get added to the normal NotificationRequest parameters. The one exception is EndpointId, which isn't copied over ๐ซถ.
The encapsulated EndpointConfiguration shares the fate of the NotificationRequest. If the NotificationRequest is rejected, the EndpointConfiguration doesn't run ๐.
ReturnCode is a parameter the gateway sends back. It shows the outcome of the command and is an integer, optionally followed by commentary ๐.
PackageList is a list of supported packages that MAY be included with error code 518 (unsupported package) ๐ฆ.
2.3.4 Notify ๐
Okay, this is where the gateway tells the Call Agent what happened. Notifications with the observed events get sent through the Notify command whenever a triggering event occurs ๐ฃ.
ReturnCode,
[PackageList]
<-- Notify(EndpointId,
[NotifiedEntity,]
RequestIdentifier,
ObservedEvents)
EndpointId is the name of the endpoint in the gateway that's sending the Notify command. It MUST be a fully qualified endpoint identifier, including the gateway's domain name ๐. The local part of the name MUST NOT use any of the wildcard conventions ๐ โโ๏ธ.
NotifiedEntity identifies the entity that asked for the notification. It matches the NotifiedEntity parameter of the NotificationRequest that triggered this notification. If the triggering request didn't have that parameter, it's absent here too. No matter what the NotifiedEntity value is, the notification MUST be sent to the current "notified entity" for the endpoint ๐.
RequestIdentifier repeats the RequestIdentifier from the NotificationRequest that triggered this notification. It's how the notification gets matched back to its request ๐งฉ. Persistent events get treated here as if they'd been included in the last NotificationRequest. An implicit NotificationRequest MAY be in place right after a restart. Its RequestIdentifier is zero ("0"). See Section 4.4.1 for details ๐.
ObservedEvents is a list of events the gateway detected and accumulated. One notification can report a list of events, and they show up in the order they were detected (FIFO) ๐.
The list only contains events that were requested in the RequestedEvents parameter of the triggering NotificationRequest. It includes events that were accumulated but not notified, events handled by the digit map that haven't matched yet, and the final event that triggered the notification or gave the final digit map match ๐ฏ. Worth noting: digits MUST be added to the list of observed events as they're accumulated, whether or not they're accumulated under the digit map ๐ข. For example, if a user enters the digits "1234" and some event E gets accumulated between the "3" and the "4", the list of observed events would be "1, 2, 3, E, 4" ๐ง . Events detected on a connection SHALL include that connection's name, like "R/qa@0A3F58" (see Section 2.1.7) ๐.
If the list of ObservedEvents hits the endpoint's capacity, an ObservedEvents Full event (see Appendix B) SHOULD be generated. The endpoint shall make sure it has room to include this event in the list of ObservedEvents ๐ซ. If the ObservedEvents Full event doesn't trigger a Notify, event processing carries on as before, digit map matching included. The subsequent events just won't go into the list of ObservedEvents ๐.
ReturnCode is a parameter the Call Agent sends back. It shows the outcome of the command and is an integer, optionally followed by commentary ๐ .
PackageList is a list of supported packages that MAY be included with error code 518 (unsupported package) ๐ฆ.
2.3.5 CreateConnection ๐
This command creates a connection between two endpoints ๐.
ReturnCode,
[ConnectionId,]
[SpecificEndPointId,]
[LocalConnectionDescriptor,]
[SecondEndPointId,]
[SecondConnectionId,]
[PackageList]
<-- CreateConnection(CallId,
EndpointId,
[NotifiedEntity,]
[LocalConnectionOptions,]
Mode,
[{RemoteConnectionDescriptor |
SecondEndpointId}, ]
[Encapsulated NotificationRequest,]
[Encapsulated EndpointConfiguration])
A connection is defined by its endpoints. The input parameters in CreateConnection give the gateway everything it needs to build its "view" of a connection ๐.
CallId identifies the call (or session) this connection belongs to. It SHOULD, at a minimum, be unique within the set of Call Agents that control the same gateways ๐. Connections in the same call SHOULD share the same call-id. The call-id doesn't carry much semantic meaning in the protocol, but it can be used to identify calls for reporting and accounting ๐. It doesn't change how the gateway handles connections ๐.
EndpointId is the identifier for the connection endpoint in the gateway where CreateConnection runs. You can fully specify it by putting a value in the EndpointId parameter, or under-specify it with the "any of" wildcard convention ๐ฒ. If the endpoint is under-specified, the gateway SHALL assign the endpoint identifier and return its full value in the SpecificEndPointId parameter of the response ๐ช. When the "any of" wildcard is used, the assigned endpoint MUST be in-service and MUST NOT already have any connections on it. If no such endpoint is available, error code 410 (no endpoint available) SHOULD be returned ๐ญ. The "all of" wildcard MUST NOT be used ๐ซ.
The NotifiedEntity is an optional parameter that sets a new "notified entity" for the endpoint ๐ฎ.
LocalConnectionOptions is an optional structure the Call Agent uses to direct how the gateway handles the connection ๐๏ธ. It can include one or more of the following fields (each field MUST NOT be supplied more than once):
- Codec compression algorithm: okay so this is the list of codecs, in order of preference ๐ You can give one or more! For interop, it is RECOMMENDED to support G.711 mu-law encoding (
"PCMU"). See Section 2.6 for how the codec selection works ๐ - Packetization period: you can give a single millisecond value or a range โจ The packetization period SHOULD NOT contradict the codec compression spec. If you pick a codec whose frame size doesn't match the packetization period and that codec gets selected, the gateway is allowed to use a packetization period that matches the frame size, even if it's different from what you asked for. In that case the gateway SHOULD choose a non-zero packetization period as close to the requested one as possible. If no packetization period is specified, the endpoint SHOULD use the default packetization period(s) for the selected codec(s) ๐ง
- Bandwidth: the allowable bandwidth, i.e., payload plus any header overhead from the transport layer and up, e.g., IP, UDP, and RTP ๐ฆ The bandwidth specification SHOULD NOT contradict the codec compression algorithm or the packetization period. If a codec is specified, the gateway is authorized to use it, even if that results in more bandwidth than specified. Any discrepancy between the bandwidth and codec specification will not be reported as an error ๐
- Type of Service: this is the class of service for the connection ๐
When the Type of Service isn't specified, the gateway SHALL use a default value of
zerounless provisioned otherwise. - Usage of echo cancellation: by default the telephony gateways always do echo cancellation on the endpoint ๐ธ But sometimes you need to turn it off for certain calls. The parameter can be
"on"(when echo cancellation is requested) or"off"(when it's turned off). It's optional. If it's left out when creating a connection and there are no other connections on the endpoint, the endpoint SHALL apply echo cancellation initially. If it's left out and there are existing connections on the endpoint, echo cancellation stays unchanged. The endpoint SHOULD then enable or disable echo cancellation when voiceband data is detected, see e.g., ITU-T recommendation V.8, V.25, and G.168. Once the voiceband data ends, the handling of echo cancellation SHALL revert to the current value of the echo cancellation parameter. It is RECOMMENDED that echo cancellation handling is left to the gateway rather than having the Call Agent specify this parameter ๐ซถ - Silence Suppression: the telephony gateways may do voice activity detection and skip sending packets during silence ๐ But for things like modem calls you need to turn that off. The parameter can be
"on"(when detection is requested) or"off"(when it's not requested). The default is"off"(unless provisioned otherwise). When voiceband data is detected, the endpoint SHOULD disable silence suppression. Once the voiceband data ends, the handling of silence suppression SHALL revert to the current value of the silence suppression parameter. - Gain Control: the telephony gateways may do gain control on the endpoint to adjust the signal level ๐ But for some modem calls, you need to turn it off. The gain control parameter can be
"automatic"or an explicit number of decibels of gain. The gain specified is added to media sent out over the endpoint (as opposed to the connection) and subtracted from media received on the endpoint. The parameter is optional. When there are no other connections on the endpoint and the parameter is left out, the default is to not perform gain control (unless provisioned otherwise), which is the same as specifying a gain of 0 decibels. If there are other connections on the endpoint and the parameter is left out, gain control is unchanged. When voiceband data is detected, the endpoint SHOULD disable gain control if needed. Once the voiceband data ends, the handling of gain control SHALL revert to the current value of the gain control parameter. It should be noted that handling gain control is normally best left to the gateway, so using this parameter is NOT RECOMMENDED ๐ โโ๏ธ - RTP security: the Call Agent can ask the gateway to encrypt the audio packets ๐ It does this by providing a key specification, as specified in RFC 2327. By default, encryption is not performed.
- Network Type: the Call Agent may tell the gateway to prepare the connection on a specified type of network ๐ฐ๏ธ If it's absent, the value is based on the network type of the gateway being used.
- Resource reservation: the Call Agent may tell the gateway to use network resource reservation for the connection ๐ See Section 2.7 for details.
The Call Agent specifies the fields it cares about in the command and leaves the rest up to the gateway ๐ For any of the parameters above that weren't explicitly included, the gateway SHOULD use the default values if possible. For a detailed list of local connection options included with this specification, check section 3.2.2.10. The set of local connection options can be extended โจ
The Mode tells you the mode of operation for this side of the connection ๐ The basic modes are "send", "receive", "send/receive", "conference", "inactive", "loopback", "continuity test", "network loop back" and "network continuity test". The expected handling of these modes is in the introduction of the "Gateway Control Commands", Section 2.3. Note that signals applied to a connection do not follow the connection mode ๐ฆ Some endpoints can't support every mode. If the command asks for a mode the endpoint doesn't support, an error SHALL be returned (error 517 - unsupported mode, is RECOMMENDED). Also, if a connection hasn't received a RemoteConnectionDescriptor yet, an error MUST be returned if someone tries to put it in any of the modes "send only", "send/receive", "conference", "network loopback", or "network continuity test", or if a signal (as opposed to detecting an event) is to be applied to the connection (error code 527 - missing RemoteConnectionDescriptor, is RECOMMENDED). The set of modes can be extended ๐
The gateway returns a ConnectionId, which uniquely identifies the connection within the endpoint, and a LocalConnectionDescriptor, which is a session description containing info about the connection, e.g., the IP address and port for the media, as defined in SDP ๐ง
The SpecificEndPointId is an optional parameter that identifies the responding endpoint ๐ธ It's returned when the EndpointId argument referred to an "any of" wildcard name and the command succeeded. When a SpecificEndPointId is returned, the Call Agent SHALL use it as the EndpointId value in successive commands referring to this connection.
The SecondEndpointId can be used instead of the RemoteConnectionDescriptor to set up a connection between two endpoints on the same gateway ๐ The connection is by definition a local connection. The SecondEndpointId can be fully specified by assigning a value to the parameter in the function call, or it can be under-specified using the "any of" wildcard convention. If it's under-specified, the gateway assigns the second endpoint identifier and returns its complete value in the SecondEndPointId parameter of the response.
When a SecondEndpointId is specified, the command really creates two connections that you can manipulate separately through ModifyConnection and DeleteConnection commands ๐ Besides the ConnectionId and LocalConnectionDescriptor for the first connection, the response to the creation gives you a SecondConnectionId parameter that identifies the second connection. The second connection is established in "send/receive" mode.
After receiving a "CreateConnection" request that didn't include a RemoteConnectionDescriptor parameter, a gateway is in an ambiguous situation ๐ญ Because it has exported a LocalConnectionDescriptor parameter, it can potentially receive packets. But because it hasn't received the other gateway's RemoteConnectionDescriptor parameter yet, it doesn't know whether the packets it receives have been authorized by the Call Agent. So it has to navigate between two risks, i.e., clipping some important announcements or listening to insane data ๐ The gateway's behavior is determined by the value of the Mode parameter:
- If the mode was set to
ReceiveOnly, the gateway MUST accept the media and transmit it through the endpoint. - If the mode was set to
Inactive,Loopback, orContinuity Test, the gateway MUST NOT transmit the media through to the endpoint.
Note that the mode values SendReceive, Conference, SendOnly, Network Loopback and Network Continuity Test don't make sense in this situation ๐
โโ๏ธ They MUST be treated as errors, and the command MUST be rejected (error code 527 - missing RemoteConnectionDescriptor, is RECOMMENDED).
The command may optionally include an encapsulated Notification Request command, which applies to the EndpointId. When it does, a RequestIdentifier parameter MUST be present, along with, optionally, other parameters of the NotificationRequest except for the EndpointId, which isn't replicated. The encapsulated NotificationRequest is executed at the same time as the connection is created. For example, when the Call Agent wants to start a call to a residential gateway, it could:
- ask the residential gateway to prepare a connection, so the user can start speaking as soon as the phone goes off hook,
- ask the residential gateway to start ringing,
- ask the residential gateway to notify the Call Agent when the phone goes off-hook.
This can all be done in a single CreateConnection command, by also sending the RequestedEvents parameters for the off-hook event, and the SignalRequests parameter for the ringing signal ๐ฅ
When these parameters are present, the creation and the NotificationRequest MUST be synchronized, which means that both MUST be accepted, or both MUST be refused ๐ซถ In our example, the CreateConnection may be refused if the gateway doesn't have enough resources, or can't get adequate resources from the local network access. The off-hook NotificationRequest can be refused in a glare condition, if the user is already off-hook. In this example, the phone must not ring if the connection can't be established, and the connection must not be established if the user is already off-hook ๐
The NotifiedEntity parameter, if present, defines the new "notified entity" for the endpoint ๐
okay so the CreateConnection command can carry an encapsulated EndpointConfiguration command ๐ , and it applies to the EndpointId. When it shows up, its parameters tag along with the normal CreateConnection parameters, except for the EndpointId, which doesn't get copied over ๐ฆ. The EndpointConfiguration can also be encapsulated together with an encapsulated NotificationRequest command. Note that both of these only apply to the EndpointId, bestie โจ
the encapsulated EndpointConfiguration is totally ride or die with the CreateConnection ๐ซถ. If the CreateConnection gets rejected, the EndpointConfiguration doesn't run at all ๐
ReturnCode is the thing the gateway sends back ๐. It tells you how the command went, and it's an integer number, optionally followed by some commentary.
PackageList is a list of supported packages that MAY be included with error code 518 (unsupported package) ๐ง
2.3.6 ModifyConnection โจ
this command is how you change the gateway's "view" of a connection ๐. That "view" covers both the local connection descriptor and the remote connection descriptor, so it's the whole vibe ๐
ReturnCode,
[LocalConnectionDescriptor,]
[PackageList]
<-- ModifyConnection(CallId,
EndpointId,
ConnectionId,
[NotifiedEntity,]
[LocalConnectionOptions,]
[Mode,]
[RemoteConnectionDescriptor,]
[Encapsulated NotificationRequest,]
[Encapsulated EndpointConfiguration])
the parameters are the same as in CreateConnection, plus a ConnectionId that identifies the connection within the endpoint ๐ฆ. You get that ConnectionId back from CreateConnection, along with the local connection descriptor. It uniquely identifies the connection within the context of the endpoint, so it's giving main character ๐. The CallId used when the connection was created MUST be included as well ๐
the EndpointId MUST be a fully qualified endpoint identifier ๐ธ. The local name MUST NOT use the wildcard conventions, no exceptions bestie ๐ญ
the ModifyConnection command can affect a connection in a few different ways ๐:
- It gives info about the other end of the connection through the RemoteConnectionDescriptor. If the parameter is omitted, it keeps its current value ๐.
- It activates or deactivates the connection by changing the Mode parameter. This can happen at any time during the connection, with arbitrary parameter values โจ. If the parameter is omitted, it keeps its current value.
- It changes the connection's parameters through the LocalConnectionOptions, like switching to a different coding scheme, changing the packetization period, or modifying how echo cancellation is handled ๐ฅ. If one or more LocalConnectionOptions parameters are omitted, then the gateway SHOULD refrain from changing that parameter from its current value, unless another parameter that needs that change is explicitly provided. For example, a codec change might require a change in silence suppression ๐. Note that if a RemoteConnectionDescriptor is supplied, then only the LocalConnectionOptions actually supplied with the ModifyConnection command will affect the codec negotiation (as described in Section 2.6) ๐ง
connections can only be fully activated if the RemoteConnectionDescriptor has been provided to the gateway ๐ฆ. The receive-only mode, however, can be activated without that descriptor, which is a lowkey plot twist ๐
the command will only return a LocalConnectionDescriptor if the local connection parameters, such as RTP ports, were modified ๐. So if you only change the mode, no LocalConnectionDescriptor comes back, periodt ๐ . Note however that including LocalConnectionOptions in the command is not a prerequisite for local connection parameter changes to occur ๐ซถ. If a connection parameter is omitted, e.g., silence suppression, the old value of that parameter is retained if possible โจ. If a parameter change forces a change in one or more unspecified parameters, the gateway is free to choose suitable values for the unspecified parameters that must change ๐. This can for instance happen if the packetization period was not specified. If the new codec supported the old packetization period, the value of this parameter would not change, since a change would not be necessary. However, if it did not support the old packetization period, it would choose a suitable value ๐ธ
the command may optionally contain an encapsulated NotificationRequest command, and in that case a RequestIdentifier parameter MUST be present ๐, plus optionally other parameters of the NotificationRequest, except for the EndpointId, which is not replicated. The encapsulated NotificationRequest runs simultaneously with the modification of the connection ๐. For example, when a connection is accepted, the calling gateway should be told to put the circuit in send-receive mode and to stop providing ringing tones. You can do this all in one ModifyConnection by also sending the RequestedEvents parameters for the on-hook event, plus an empty SignalRequests parameter to stop the ringing ๐
when these parameters are present, the modification and the NotificationRequest MUST be synchronized, which means both MUST be accepted, or both MUST be refused ๐ญ๐ซถ. No splitting the difference, bestie ๐
the NotifiedEntity parameter, if present, defines the new "notified entity" for the endpoint ๐
the command may carry an encapsulated EndpointConfiguration command that applies to the same endpoint ๐ง. When it's there, its parameters are included with the normal ModifyConnection parameters, except for the EndpointId, which isn't replicated ๐ฆ. The EndpointConfiguration may be encapsulated together with an encapsulated NotificationRequest command ๐
the encapsulated EndpointConfiguration shares the fate of the ModifyConnection command. If the ModifyConnection is rejected, the EndpointConfiguration is not executed ๐
ReturnCode is a parameter returned by the gateway. It indicates the outcome of the command and consists of an integer number optionally followed by commentary ๐
PackageList is a list of supported packages that MAY be included with error code 518 (unsupported package) ๐ธ
2.3.7 DeleteConnection (from the Call Agent) ๐
okay bestie, this is the command the Call Agent uses to end a connection ๐โจ and as a bonus side quest, it also collects stats on how the connection went ๐ iconic.
ReturnCode,
ConnectionParameters,
[PackageList]
<-- DeleteConnection(CallId,
EndpointId,
ConnectionId,
[NotifiedEntity,]
[Encapsulated NotificationRequest,]
[Encapsulated EndpointConfiguration])
The endpoint identifier in this form of the DeleteConnection command SHALL be fully qualified ๐. Wildcard conventions SHALL NOT be used, no cap ๐ โโ๏ธ.
The ConnectionId tells everyone which connection to delete ๐ฆ. The CallId that was used when the connection got created gets included too ๐.
NotifiedEntity, if it's there, sets the new "notified entity" for the endpoint ๐ธ.
For IP multicast, connections can be deleted individually and independently, so it's giving freedom ๐ง. But in the unicast case, where a connection has two ends, you have to send a DeleteConnection command to both gateways in the connection ๐ฏโโ๏ธ. After the connection is deleted, the media streams it used to support are no longer available ๐ญ. Any media packets that arrive for the old connection just get discarded, and no new media packets for that stream get sent. Gone, bestie.
After the connection has been deleted, any loopback that was requested for it must be cancelled ๐. The one exception is if the endpoint has another connection that's also requesting loopback.
In response to the DeleteConnection command, the gateway sends back a list of connection parameters that describe statistics for the connection ๐.
When the connection was for an Internet media stream, these parameters are:
Number of packets sent: The total number of media packets transmitted by the sender since starting transmission on this connection. In the case of RTP, the count is not reset if the sender changes its synchronization source identifier (SSRC, as defined in RTP), for example as a result of a ModifyConnection command. The value is zero if the connection was always set in "receive only" mode and no signals were applied to the connection.
Number of octets sent: The total number of payload octets (i.e., not including header or padding) transmitted in media packets by the sender since starting transmission on this connection. In the case of RTP, the count is not reset if the sender changes its SSRC identifier, for example as a result of a ModifyConnection command. The value is zero if the connection was always set in "receive only" mode and no signals were applied to the connection.
Number of packets received: The total number of media packets received by the sender since starting reception on this connection. In the case of RTP, the count includes packets received from different SSRC, if the sender used several values. The value is zero if the connection was always set in "send only" mode.
Number of octets received: The total number of payload octets (i.e., not including header, e.g., RTP, or padding) transmitted in media packets by the sender since starting transmission on this connection. In the case of RTP, the count includes packets received from different SSRC, if the sender used several values. The value is zero if the connection was always set in "send only" mode.
Number of packets lost: The total number of media packets that have been lost since the beginning of reception. This number is defined to be the number of packets expected less the number of packets actually received, where the number of packets received includes any which are late or duplicates. For RTP, the count includes packets received from different SSRC, if the sender used several values. Thus packets that arrive late are not counted as lost, and the loss may be negative if there are duplicates. The count includes packets received from different SSRC, if the sender used several values. The number of packets expected is defined to be the extended last sequence number received, as defined next, less the initial sequence number received. The count includes packets received from different SSRC, if the sender used several values. The value is zero if the connection was always set in "send only" mode.
Interarrival jitter: An estimate of the statistical variance of the media packet interarrival time measured in milliseconds and expressed as an unsigned integer. For RTP, the interarrival jitter J is defined to be the mean deviation (smoothed absolute value) of the difference D in packet spacing at the receiver compared to the sender for a pair of packets. Detailed computation algorithms are found in RFC 1889. The count includes packets received from different SSRC, if the sender used several values. The value is zero if the connection was always set in "send only" mode.
Average transmission delay: An estimate of the network latency, expressed in milliseconds. For RTP, this is the average value of the difference between the NTP timestamp indicated by the senders of the RTCP messages and the NTP timestamp of the receivers, measured when the messages are received. The average is obtained by summing all the estimates, then dividing by the number of RTCP messages that have been received. When the gateway's clock is not synchronized by NTP, the latency value can be computed as one half of the round trip delay, as measured through RTCP. When the gateway cannot compute the one way delay or the round trip delay, the parameter conveys a null value.
For a detailed definition of these variables, refer to RFC 1889.
When the connection was set up over a LOCAL interconnect, the meaning of these parameters is defined as follows:
Number of packets sent: Not significant - MAY be omitted.
Number of octets sent: The total number of payload octets transmitted over the local connection.
Number of packets received: Not significant - MAY be omitted.
Number of octets received: The total number of payload octets received over the connection.
Number of packets lost: Not significant - MAY be omitted. A value of zero is assumed.
Interarrival jitter: Not significant - MAY be omitted. A value of zero is assumed.
Average transmission delay: Not significant - MAY be omitted. A value of zero is assumed.
The set of connection parameters can be extended. Also, the meaning may be further defined by other types of networks, which MAY furthermore elect to not return all, or even any, of the above specified parameters.
The command may optionally contain an encapsulated Notification Request command, in which case a RequestIdentifier parameter MUST be present, as well as, optionally, other parameters of the NotificationRequest with the exception of the EndpointId, which is not replicated. The encapsulated NotificationRequest is executed simultaneously with the deletion of the connection. For example, when a user hang-up is notified, the gateway should be instructed to delete the connection and to start looking for an off-hook event.
This can be accomplished in a single DeleteConnection command, by also transmitting the RequestedEvents parameters, for the off-hook event, and an empty SignalRequests parameter.
When these parameters are present, the DeleteConnection and the NotificationRequest must be synchronized, which means that both MUST be accepted, or both MUST be refused. ๐ค
The command may carry an encapsulated EndpointConfiguration command that will apply to the same endpoint. When this command is present, the parameters of the EndpointConfiguration command are included with the normal parameters of the DeleteConnection, with the exception of the EndpointId, which is not replicated. The EndpointConfiguration command may be encapsulated together with an encapsulated NotificationRequest command.
The encapsulated EndpointConfiguration command shares the fate of the DeleteConnection command. If the DeleteConnection is rejected, the EndpointConfiguration is not executed. Rip, but that's how it goes ๐.
ReturnCode is a parameter returned by the gateway. It indicates the outcome of the command and consists of an integer number optionally followed by commentary ๐.
PackageList is a list of supported packages that MAY be included with error code 518 (unsupported package) ๐ฆ.
2.3.8 DeleteConnection (from the gateway) ๐
In some rare circumstances, a gateway may have to clear a connection, for example because it has lost the resource associated with the connection, or because it has detected that the endpoint is no longer capable or willing to send or receive media. Rare, but it happens ๐. The gateway can then terminate the connection by using a variant of the DeleteConnection command:
ReturnCode,
[PackageList]
<-- DeleteConnection(CallId,
EndpointId,
ConnectionId,
ReasonCode,
Connection-parameters)
The EndpointId, in this form of the DeleteConnection command, MUST be fully qualified. Wildcard conventions MUST NOT be used ๐ซ.
The ReasonCode is a text string that starts with a numeric reason code and optionally is followed by a descriptive text string. The reason code indicates the cause of the DeleteConnection. A list of reason codes can be found in Section 2.5 ๐.
In addition to the call, endpoint and connection identifiers, the gateway will also send the connection parameters that would have been returned to the Call Agent in response to a DeleteConnection command ๐.
ReturnCode is a parameter returned by the Call Agent. It indicates the outcome of the command and consists of an integer number optionally followed by commentary ๐.
PackageList is a list of supported packages that MAY be included with error code 518 (unsupported package) ๐ฆ.
Note that use of this command is generally discouraged and should only be done as a last resort ๐จ. If a connection can be sustained, deletion of it should be left to the discretion of the Call Agent, which is in a far better position to make intelligent decisions in this area. The Call Agent is literally the main character here ๐.
2.3.9 DeleteConnection (multiple connections from the Call Agent) ๐ฆ
okay so the Call Agent can delete a whole bunch of connections in one go with a variation of DeleteConnection, bestie ๐ the one rule is you can't wrap other commands inside this version, that's a hard no ๐ โโ๏ธ. It's giving efficiency. The command can wipe every connection tied to a Call for an endpoint:
ReturnCode,
[PackageList]
<-- DeleteConnection(CallId,
EndpointId)
Here the EndpointId MUST NOT use the "any of" wildcard ๐ซ. Every connection for the endpoint(s) with that CallId gets deleted. The command still succeeds if there were no connections with that CallId, as long as the EndpointId is valid โจ. But if the EndpointId is invalid, it fails ๐. It also doesn't hand back any individual statistics or call parameters, so don't go looking for them ๐.
It can also nuke every connection that terminates in a given endpoint:
ReturnCode,
[PackageList]
<-- DeleteConnection(EndpointId)
Again, the EndpointId MUST NOT use the "any of" wildcard ๐ซ. And again, it succeeds even if there were no connections on the endpoint(s) ๐ซถ.
Last but not least, the hierarchy of endpoint names is so iconic. The Call Agent can delete every connection that belongs to a whole group of endpoints ๐. In this case the "local name" part of the EndpointId uses the "all of" wildcard convention. The "any of" convention SHALL NOT be used ๐
โโ๏ธ. Say endpoint names are a physical interface name plus a circuit number, like X35V3+A4/13. The Call Agent can swap the circuit number for the "all of" wild card character *, giving X35V3+A4/*. That wildcard tells the gateway to delete all the connections attached to circuits on the physical interface X35V3+A4 ๐ง.
After all the connections have been deleted, any loopback that has been requested for the connections MUST be cancelled by the gateway ๐.
This command does not return any individual statistics or call parameters, which is the same deal as before ๐.
ReturnCode is a parameter the gateway sends back. It tells you how the command went, and it's an integer number, optionally followed by commentary ๐.
PackageList is a list of supported packages that MAY be included with error code 518 (unsupported package) ๐.
2.3.10 AuditEndpoint ๐
the Call Agent uses AuditEndPoint to check the status of a given endpoint, and honestly it's the main character of status checks ๐ธ.
ReturnCode,
EndPointIdList,|{
[RequestedEvents,]
[QuarantineHandling,]
[DigitMap,]
[SignalRequests,]
[RequestIdentifier,]
[NotifiedEntity,]
[ConnectionIdentifiers,]
[DetectEvents,]
[ObservedEvents,]
[EventStates,]
[BearerInformation,]
[RestartMethod,]
[RestartDelay,]
[ReasonCode,]
[MaxMGCPDatagram,]
[Capabilities]}
[PackageList]
<-- AuditEndPoint(EndpointId,
[RequestedInfo])
The EndpointId says which endpoint(s) get audited. The "any of" wildcard convention MUST NOT be used ๐ซ.
The EndpointId also says which endpoint(s) get audited, and this is where the "all of" wildcard convention comes in ๐ฆ. It can start auditing a group of endpoints (regardless of their service-state) ๐. If you go with this convention, the gateway SHALL return the list of endpoint identifiers that match the wildcard in the EndPointIdList parameter. That list is just one or more SpecificEndpointIds, each supplied separately ๐. When the "all of" wildcard is used, RequestedInfo SHOULD NOT be included, and if it is included anyway, it MUST be ignored ๐. Heads up though, the "all of" wildcard can generate a seriously large EndPointIdList ๐ญ. If the list is considered too large, the gateway returns an error (error code 533 - response too large), which is RECOMMENDED ๐ .
When a non-wildcard EndpointId is specified, the RequestedInfo parameter describes what info is being asked for. It might be empty, and that's fine ๐ซง. These are the endpoint info items you can audit with this command:
RequestedEvents, DigitMap, SignalRequests, RequestIdentifier,
QuarantineHandling, NotifiedEntity, ConnectionIdentifiers,
DetectEvents, ObservedEvents, EventStates, BearerInformation,
RestartMethod, RestartDelay, ReasonCode, PackageList,
MaxMGCPDatagram, and Capabilities.
The list can be extended by extension parameters ๐งฉ. The response will then include info about each item you asked for. Supported parameters with empty values MUST always be returned ๐. But if an endpoint gets asked about a parameter it doesn't understand, the endpoint MUST NOT generate an error. Instead, that parameter MUST be omitted from the response ๐. Here's the breakdown:
- RequestedEvents: The current value of RequestedEvents the endpoint is using, including the action(s) and event parameters attached to each event. If no actions are included, the default action is assumed. Persistent events are included in the list. If an embedded NotificationRequest is active, RequestedEvents reflects the events requested in that embedded NotificationRequest, not any surrounding RequestedEvents (whether embedded or not) ๐ฏ.
- DigitMap: The digit map the endpoint is currently using. The parameter will be empty if the endpoint doesn't have a digit map ๐ข.
- SignalRequests: A list of the Time-Out signals that are currently active, On/Off signals that are currently "on" for the endpoint (with or without parameter), and any pending Brief signals. Time-Out signals that have already timed out, and Brief signals that are currently playing, are not included. Any signal parameters included in the original SignalRequests will be included ๐ก.
- RequestIdentifier: The RequestIdentifier for the last NotificationRequest received by this endpoint. That includes NotificationRequests encapsulated in other commands. If no NotificationRequest has been received since reboot/restart, the value zero is returned 0๏ธโฃ.
- QuarantineHandling: The QuarantineHandling for the last NotificationRequest received by this endpoint. If QuarantineHandling wasn't included, or no notification request has been received, the default values are returned ๐ก๏ธ.
- DetectEvents: The value of the most recently received DetectEvents parameter, plus any persistent events implemented by the endpoint. If no DetectEvents parameter has been received, the (possibly empty) list only includes persistent events ๐.
- NotifiedEntity: The current "notified entity" for the endpoint ๐ฎ.
- ConnectionIdentifiers: The list of ConnectionIdentifiers for all connections that currently exist for the specified endpoint ๐.
- ObservedEvents: The current list of observed events for the endpoint ๐๏ธ.
- EventStates: For events that have auditable states attached, this is the event matching the state the endpoint is in, like off-hook if the endpoint is off-hook ๐. The definition of each individual event will say whether it has an auditable state, so go read those too ๐.
- BearerInformation: The value of the last received BearerInformation parameter for this endpoint. That includes the case where BearerInformation was provisioned. The parameter will be empty if the endpoint hasn't received a BearerInformation parameter and no value was provisioned ๐ง.
- RestartMethod: "restart" if the endpoint is in-service and operating normally, or if it's in the process of becoming in-service (a non-zero RestartDelay will indicate the latter). Otherwise, it's the restart method parameter from the last RestartInProgress command issued (or that should have been issued) by the endpoint. A "disconnected" endpoint will only report "disconnected" for as long as it actually is disconnected, and "restart" gets reported once it's no longer disconnected. Also, "cancel-graceful" won't be reported, but "graceful" might (see Section 4.4.5 for further details) ๐.
- RestartDelay: The value of the restart delay parameter if a RestartInProgress command were to be issued by the endpoint at the time of this response, or zero if that command wouldn't include this parameter โณ.
- ReasonCode: The value of the ReasonCode parameter from the last RestartInProgress or DeleteConnection command the gateway issued for the endpoint. If the endpoint's state is normal, the special value 000 is returned ๐งพ.
- PackageList: The packages the endpoint supports, including package version numbers. For backwards compatibility, support for this parameter is OPTIONAL, though implementations with package versions higher than zero SHOULD support it ๐ฆ.
- MaxMGCPDatagram: The maximum size of an MGCP datagram, in bytes, that the endpoint can receive (see Section 3.5.4). The value excludes any lower layer overhead. For backwards compatibility, support for this parameter is OPTIONAL. If no value is returned, the default maximum MGCP datagram size SHOULD be assumed ๐.
- Capabilities: The capabilities for the endpoint, similar to the LocalConnectionOptions parameter, including packages and connection modes. Extensions MAY be included as well. If any unknown capabilities are reported, they MUST simply be ignored. If you need to say that some parameters, such as silence suppression, only work with some codecs, then the gateway MUST return several capability sets. Each of those sets may include the following ๐๏ธ:
- Compression Algorithm: A list of supported codecs. The rest of the parameters in the capability set apply to all codecs in this list ๐ต.
- Packetization Period: A single value or a range may be specified โฑ๏ธ.
- Bandwidth: A single value or a range corresponding to the range for packetization periods may be specified (assuming no silence suppression) ๐ถ.
- Echo Cancellation: Whether echo cancellation is supported or not for the endpoint ๐.
- Silence Suppression: Whether silence suppression is supported or not ๐คซ.
- Gain Control: Whether gain control is supported or not ๐๏ธ.
- Type of Service: Whether type of service is supported or not ๐ท๏ธ.
- Resource Reservation: Whether resource reservation is supported or not ๐ช.
- Security: Whether media encryption is supported or not ๐.
- Type of network: The type(s) of network supported ๐.
- Packages: A list of supported packages. The first package in the list is the default package ๐ฅ.
- Modes: A list of supported connection modes ๐.
After that, the Call Agent may decide to use the AuditConnection command to get more info about the connections ๐ต๏ธโโ๏ธ.
If no info was requested and the EndpointId refers to a valid endpoint (in-service or not), the gateway just sends back a positive acknowledgement โ .
ReturnCode is a parameter the gateway sends back. It tells you how the command went, and it's an integer number, optionally followed by commentary ๐.
Note that PackageList MAY also be included with error code 518 (unsupported package) ๐.
2.3.11 AuditConnection โจ
okay so AuditConnection is the Call Agent's little check-in ๐ซถ It's how you ask a connection what it's currently set up with, no cap.
ReturnCode,
[CallId,]
[NotifiedEntity,]
[LocalConnectionOptions,]
[Mode,]
[RemoteConnectionDescriptor,]
[LocalConnectionDescriptor,]
[ConnectionParameters,]
[PackageList]
<-- AuditConnection(EndpointId,
ConnectionId,
RequestedInfo)
The EndpointId parameter tells you which endpoint is handling the connection. Wildcards are a no-go here, the wildcard conventions SHALL NOT be used ๐
โโ๏ธ
ConnectionId is the ID of the connection you're auditing, and it only makes sense inside the endpoint you named ๐ง
RequestedInfo is the list of what you want to know. It can be totally empty too! The stuff you can audit is CallId, NotifiedEntity, LocalConnectionOptions, Mode, RemoteConnectionDescriptor, LocalConnectionDescriptor, and ConnectionParameters ๐
The response comes back with info about each item you asked for:
CallIdis the call the connection belongs to ๐NotifiedEntityis the current "notified entity" for the connection. It's the same one the endpoint has too, and it's only here for backwards compatibility ๐ฐ๏ธLocalConnectionOptionsis the most recent set of options that was actually supplied for the connection. Leaving it out of a command doesn't change this value. Default parameters that were left out of the latestLocalConnectionOptionswon't show up. Options that keep their value acrossModifyConnectioncommands, and that were sent in an earlier command for the connection, are also included, whether or not they came in the latest one ๐ธModeis the connection's current mode ๐RemoteConnectionDescriptoris the one that was given to the gateway for the connection ๐จLocalConnectionDescriptoris the one the gateway handed back for the connection ๐ฆConnectionParametershas the current values of the connection parameters โจ
If you didn't ask for any info and the EndpointId is valid, the gateway just checks that the connection exists. If it does, you get a positive acknowledgement ๐ฅฐ But it's an in-service thing: the endpoint must be in-service for this to work, since out-of-service endpoints don't have any connections at all ๐
ReturnCode is sent back by the gateway. It tells you how the command went, and it's an integer followed by optional commentary ๐
PackageList is a list of supported packages that MAY be included with error code 518 (unsupported package). Basically, that's the gateway saying "hey, here's what I do support" ๐
2.3.12 RestartInProgress ๐
Okay this one is the gateway's announcement that an endpoint, or a whole group of endpoints, is going in-service or out-of-service ๐ข
ReturnCode,
[NotifiedEntity,]
[PackageList]
<-- RestartInProgress(EndPointId,
RestartMethod,
[RestartDelay,]
[ReasonCode])
EndPointId is the endpoint or endpoints getting put in-service or out-of-service. The "all of" wildcard convention may be used to hit a whole group managed by the same Call Agent, like every endpoint on a specified interface, or every endpoint on a given gateway ๐ The "any of" wildcard convention SHALL NOT be used ๐ซ
RestartMethod is the type of restart. These are the ones defined so far:
"graceful"means the endpoints will be taken out-of-service after the specified delay. Established connections aren't affected yet, but the Call Agent SHOULD refrain from setting up new connections, and SHOULD try to gracefully tear down the existing ones ๐๏ธ"forced"means the endpoints are yanked out-of-service abruptly ๐ญ Any established connections, if there are any, are lost."restart"means service comes back on the endpoints after the specified "restart delay", so they're in-service again ๐ They're in their clean default state, and no connections are currently established on them."disconnected"means the endpoint lost its connection and is trying to get connectivity back (see Section 4.4.7) ๐ก The "restart delay" is how many seconds it's been disconnected. Established connections are not affected."cancel-graceful"means the gateway is taking back an earlier"graceful"restart command. The endpoints are still in-service ๐
The list of restart methods may be extended, so keep your eyes open ๐
The optional "restart delay" is a number of seconds. If the number is missing, the delay MUST be considered null (i.e., zero) ๐ซง For "graceful", a null delay means the Call Agent SHOULD simply wait for the existing connections to end naturally, and not set up new ones. The restart delay is always null for "forced" and "cancel-graceful", so the restart delay parameter MUST NOT be used with those restart methods ๐
โโ๏ธ And when the gateway sends a "restart" or "graceful" RestartInProgress with a non-zero restart delay, the gateway SHOULD send an updated RestartInProgress once that delay has passed โฐ
A restart delay of null for "restart" means service has already been restored ๐ That usually happens after gateway startup or reboot. If a reboot changes the gateway's IP address, the Call Agent MAY wish to either flush its DNS cache for the gateway's domain name or resolve that domain name by querying the DNS, no matter the TTL of the current DNS resource record for the restarted gateway ๐
The optional reason code parameter tells you why the restart happened ๐งพ
Gateways SHOULD send a "graceful" or "forced" RestartInProgress for the relevant endpoints as a courtesy to the Call Agent when they go out-of-service. That could be a shutdown, or a network management system taking them offline ๐ซถ Still, the Call Agent cannot rely on always getting that message. Gateways MUST send a "restart" RestartInProgress (for the relevant endpoints) with a null delay to their Call Agent when they're back in-service, following the restart procedure in Section 4.4.6. Call Agents can rely on getting this one ๐
Also, gateways MUST send a "disconnected" RestartInProgress (for the relevant endpoints) to their current "notified entity", following the "disconnected" procedure in Section 4.4.7 ๐ธ
The RestartInProgress goes to the current "notified entity" for the EndpointId in question. A default Call Agent, aka "notified entity", is expected to be provisioned, so after a reboot or restart the default Call Agent is always the "notified entity" for the endpoint ๐ง Gateways SHOULD take full advantage of wild-carding, so that when several endpoints restart and they're all managed by the same Call Agent, you don't end up with a pile of RestartInProgress messages ๐ฆ
ReturnCode is sent back by the Call Agent. It shows how the command turned out, and it's an integer followed by optional commentary โจ
A NotifiedEntity may also come back with the Call Agent's response to RestartInProgress. This SHOULD normally only happen for "restart" or "disconnected" (see also Sections 4.4.6 and 4.4.7) ๐
- If the response says success (return code 200 - transaction executed), the restart finished properly, and the NotifiedEntity that came back is the new "notified entity" for the endpoint(s) ๐ฅณ
- If the response from the Call Agent says there was an error, the restart did not finish properly. If a NotifiedEntity came back with it, that's the new "notified entity" for the endpoint(s), and it MUST be used when retrying the restart (as a new transaction). This SHOULD only be done with error code 521 (endpoint redirected) ๐
Note that this behaviour of returning a NotifiedEntity is only defined for RestartInProgress responses. It SHOULD NOT be done for responses to other commands, and any other behaviour is undefined ๐
PackageList is a list of supported packages that MAY be included with error code 518 (unsupported package) ๐
2.4 Return Codes and Error Codes ๐
Okay bestie, every MGCP command gets an acknowledgment back ๐, and that ack carries a return code telling you how the command went. It's an integer, and the ranges mean:
- values between
000and099= response acknowledgement ๐ซถ - values between
100and199= provisional response โณ - values between
200and299= successful completion โจ - values between
400and499= transient error ๐ง๏ธ - values between
500and599= permanent error ๐ - values between
800and899= package specific response codes ๐
The 4XX vs 5XX difference is kind of iconic. With a transient error, the Call Agent can reasonably expect that a similar request might get honored later ๐ฆ. Sometimes the endpoint has to change state first, like hook state for 401 or 402, resource availability for 403, or bandwidth for 404.
Permanent errors (500 to 599) are the ones that won't just disappear with time ๐ญ. They come from protocol errors, incompatibility between the endpoint and the Call Agent, or something the Call Agent has no control over. Think unsupported capabilities, errors on interfaces tied to the endpoint, or missing or incorrect info in the request.
Here are the codes that have been defined so far ๐ธ:
000Response Acknowledgement.100The transaction is currently running. The real completion message comes later.101The transaction is queued up. The real completion message comes later.200The requested transaction ran fine. This one works as a success response to any command.250The connection got deleted. This one only works as a success response to a DeleteConnection command.400The transaction couldn't run because of some unspecified transient error.401The phone is already off hook.402The phone is already on hook.403The transaction couldn't run because the endpoint doesn't have enough resources right now.404Not enough bandwidth right now.405The transaction couldn't run because the endpoint is"restarting".406Transaction time-out. It didn't finish in a reasonable time, so it got aborted.407Transaction aborted by some outside action, like a ModifyConnection getting aborted by a DeleteConnection.409The transaction couldn't run because of internal overload.410No endpoint available. A valid"any of"wildcard was used, but nothing was free to handle it.500The transaction couldn't run because the endpoint is unknown.501The transaction couldn't run because the endpoint isn't ready. This includes when it's out-of-service.502The transaction couldn't run because the endpoint doesn't have enough resources (and this one's permanent).503"All of"wildcard too complicated.504Unknown or unsupported command.505Unsupported RemoteConnectionDescriptor. This SHOULD be used when one or more mandatory parameters or values in the RemoteConnectionDescriptor aren't supported.506Can't satisfy both LocalConnectionOptions and RemoteConnectionDescriptor. This SHOULD be used when they contain mandatory parameters or values that conflict with each other and/or can't be supported at the same time. (Codec negotiation failure is the exception, that's534.)507Unsupported functionality. Some unspecified functionality needed for the command isn't supported. There are other codes for specific unsupported stuff (like508,511, etc.), so this SHOULD only be used if no more specific code fits.508Unknown or unsupported quarantine handling.509Error in RemoteConnectionDescriptor. This SHOULD be used when there's a syntax or semantic error in it.510The transaction couldn't run because of some unspecified protocol error. Automatic recovery from that is super hard, so this SHOULD only be used as a last resort ๐.511The transaction couldn't run because the command had an unrecognized extension. This SHOULD be used for unsupported critical parameter extensions ("X+").512The gateway isn't equipped to detect one of the requested events.513The gateway isn't equipped to generate one of the requested signals.514The gateway can't send the specified announcement.515The transaction refers to an incorrect connection-id (maybe it was already deleted).516The transaction refers to an unknown call-id, or the call-id is wrong (for example, the connection-id isn't associated with this call-id).517Unsupported or invalid mode.518Unsupported or unknown package. It is RECOMMENDED to include a PackageList parameter with the supported packages in the response, especially when the Call Agent is the one generating the response ๐.519The endpoint doesn't have a digit map.520The transaction couldn't run because the endpoint is"restarting". Usually that's transient, so405SHOULD be used instead. This code only hangs around for backwards compatibility.521Endpoint redirected to another Call Agent. The redirection behavior is only well-defined when this shows up as a response to a RestartInProgress command.522No such event or signal. The request pointed at an event or signal that isn't defined in the relevant package (which could be the default package).523Unknown action or illegal combination of actions.524Internal inconsistency in LocalConnectionOptions.525Unknown extension in LocalConnectionOptions. This SHOULD be used for unsupported mandatory vendor extensions ("x+").526Insufficient bandwidth. If it's a transient one,404SHOULD be used instead.527Missing RemoteConnectionDescriptor.528Incompatible protocol version.529Internal hardware failure.530CAS signaling protocol error.531Failure of a grouping of trunks (for example, a facility failure).532Unsupported value(s) in LocalConnectionOptions.533Response too large.534Codec negotiation failure.535Packetization period not supported.536Unknown or unsupported RestartMethod.537Unknown or unsupported digit map extension.538Event/signal parameter error (missing, erroneous, unsupported, unknown, and so on).539Invalid or unsupported command parameter. This SHOULD only be used when the parameter is neither a package nor a vendor extension parameter.540Per endpoint connection limit exceeded.541Invalid or unsupported LocalConnectionOptions. This SHOULD only be used when the LocalConnectionOptions is neither a package nor a vendor extension LocalConnectionOptions.
The set of return codes may get extended in a future version of the protocol ๐ฎ. When an implementation gets a return code it doesn't know or support, it SHOULD treat it like this:
- Unknown
0xxcode is treated as000. - Unknown
1xxcode is treated as100. - Unknown
2xxcode is treated as200. - Unknown
3xxcode is treated as521. - Unknown
4xxcode is treated as400. - Unknown
5xx-9xxcode is treated as510.
2.5 Reason Codes ๐ง
Reason codes are how the gateway explains why it's deleting a connection when it tells the Call Agent ๐ฃ. They can also show up in a RestartInProgress command to explain why the endpoint is restarting.
The reason code is an integer, and these values have been defined:
000Endpoint state is normal. This one is only used in responses to audit requests.900Endpoint malfunctioning.901Endpoint taken out-of-service.902Loss of lower layer connectivity (for example, downstream sync).903QoS resource reservation was lost.904Manual intervention.905Facility failure (for example, DS-0 failure).
The set of reason codes can be extended too ๐.
2.6. Use of Local Connection Options and Connection Descriptors โจ
Okay so, like I said before, setting up a bi-directional connection takes at least 3 steps ๐
- The Call Agent asks the first gateway to "create a connection" on an endpoint. The gateway allocates resources to that connection and responds by giving back a "session description" (called its
LocalConnectionDescriptor). The session description holds the info another party needs to send packets towards the new connection ๐ - The Call Agent then asks the second gateway to "create a connection" on an endpoint. This command carries the "session description" from the first gateway (now called the
RemoteConnectionDescriptor). The gateway allocates resources to its connection and responds with its own "session description" (LocalConnectionDescriptor) ๐ซถ - The Call Agent uses a "modify connection" command to give this second "session description" (now the
RemoteConnectionDescriptor) to the first endpoint. Once that's done, communication can go both ways ๐ฆ
When the Call Agent sends a Create or Modify Connection command, there are three parameters deciding which media that connection supports ๐
LocalConnectionOptions: The Call Agent gives this to control the media parameters the gateway uses for the connection. When it's supplied, the gateway MUST conform to these media parameters until either the connection is deleted, or a ModifyConnection command with new media parameters (LocalConnectionOptionsorRemoteConnectionDescriptor) arrives ๐RemoteConnectionDescriptor: The Call Agent gives this to share the media parameters supported by the other side of the connection. When it's supplied, the gateway MUST conform to these media parameters until either the connection is deleted, or a ModifyConnection command with new media parameters (LocalConnectionOptionsorRemoteConnectionDescriptor) arrives ๐ธLocalConnectionDescriptor: The gateway gives this to the Call Agent to share the media parameters it supports for the connection. When it's supplied, the gateway MUST honor those media parameters until either the connection is deleted, or the gateway issues a newLocalConnectionDescriptorfor that connection ๐ง
Now, when picking which codec(s) go in the LocalConnectionDescriptor, a gateway has to look at three lists of codecs ๐
- A list of codecs allowed by the
LocalConnectionOptionsin the current command (either explicitly by encoding method or implicitly by bandwidth and/or packetization period). - A list of codecs in the
RemoteConnectionDescriptorin the current command. - An internal list of codecs that the gateway can support for the connection. A gateway MAY support one or more codecs for a given connection.
Codec selection (including all the relevant media parameters) goes like this, step by step ๐ฅ
- An approved list of codecs is formed by taking the intersection of the internal list of codecs and the codecs allowed by the
LocalConnectionOptions. IfLocalConnectionOptionsweren't provided in the current command, the approved list just contains the internal list of codecs. - If the approved list of codecs is empty, a codec negotiation failure has happened and an error response is generated (error code 534 - codec negotiation failure, is RECOMMENDED) ๐
- Otherwise, a negotiated list of codecs is formed by taking the intersection of the approved list of codecs and the codecs allowed by the
RemoteConnectionDescriptor. If aRemoteConnectionDescriptorwasn't provided in the current command, the negotiated list just contains the approved list of codecs. - If the negotiated list of codecs is empty, a codec negotiation failure has happened and an error response is generated (error code 534 - codec negotiation failure, is RECOMMENDED) ๐ญ
- Otherwise, codec negotiation has succeeded, and the negotiated list of codecs is returned in the
LocalConnectionDescriptor๐
Note that both LocalConnectionOptions and the RemoteConnectionDescriptor can contain a list of codecs ordered by preference. When both are supplied in the current command, the gateway MUST adhere to the preferences in the LocalConnectionOptions ๐
Bestie, that last bit is the tiebreaker. When both show up, the LocalConnectionOptions preferences win ๐
2.7. Resource Reservations ๐ฆ
The gateways can be told to make a reservation, for example using RSVP, on a given connection. When a reservation is needed, the call agent specifies the reservation profile to use, which is either "controlled load" or "guaranteed service". Asking for "best effort" service means no reservation, and it's the default value of this parameter in a CreateConnection command. For a ModifyConnection command, the default is simply to keep the current value. When a reservation has been asked for on a connection, the gateway will:
- start emitting RSVP "PATH" messages if the connection is in "send-only", "send-receive", "conference", "network loop back" or "network continuity test" mode (if a suitable remote connection descriptor has been received,).
- start emitting RSVP "RESV" messages as soon as it receives "PATH" messages if the connection is in "receive-only", "send-receive", "conference", "network loop back" or "network continuity test" mode.
The RSVP filters get worked out from the connection's characteristics. The RSVP resource profiles get worked out from the connection's codecs, bandwidth and packetization period ๐
3. Media Gateway Control Protocol ๐
The Media Gateway Control Protocol (MGCP) implements the media gateway control interface as a set of transactions. Each transaction is a command plus a mandatory response. There are nine commands ๐ง
- EndpointConfiguration
- CreateConnection
- ModifyConnection
- DeleteConnection
- NotificationRequest
- Notify
- AuditEndpoint
- AuditConnection
- RestartInProgress
The first five commands are sent by the Call Agent to a gateway. The Notify command is sent by the gateway to the Call Agent. The gateway may also send a DeleteConnection as defined in Section 2.3.8. The Call Agent may send either of the Audit commands to the gateway, and the gateway may send a RestartInProgress command to the Call Agent ๐
3.1. General Description โจ
All commands are made up of a Command header, optionally followed by a session description.
All responses are made up of a Response header, optionally followed by session description information.
Headers and session descriptions are encoded as a set of text lines, separated by a carriage return and line feed character (or, optionally, a single line-feed character). The session descriptions are preceded by an empty line ๐
MGCP uses a transaction identifier to match commands with responses. The transaction identifier is encoded as a component of the command header and repeated as a component of the response header (see sections 3.2.1.2 and 3.3) ๐
Note that an ABNF grammar for MGCP is provided in Appendix A. Commands and responses SHALL be encoded in accordance with the grammar, which, per RFC 2234, is case-insensitive except for the SDP part. Similarly, implementations SHALL be capable of decoding commands and responses that follow the grammar. Additionally, it is RECOMMENDED that implementations tolerate additional linear white space ๐ซถ
Some productions allow for quoted strings, which can be necessary to avoid syntax problems. Where the quoted string form is used, the contents will be UTF-8 encoded [20], and the actual value provided is the unquoted string (UTF-8 encoded). Where both a quoted and unquoted string form are allowed, either form can be used provided it does not otherwise violate the grammar ๐ธ
In the following, we give more detail on the format of MGCP commands and responses ๐ง
3.2. Command Header ๐
The command header is made up of:
- A command line, identifying the requested action or verb, the transaction identifier, the endpoint the action is requested towards, and the MGCP protocol version,
- A set of zero or more parameter lines, each made up of a parameter name followed by a parameter value.
Unless otherwise noted or dictated by other referenced standards (e.g., SDP), each component in the command header is case insensitive. This goes for verbs as well as parameters and values, and hence all comparisons MUST treat upper and lower case, and combinations of these, as being equal ๐
3.2.1. Command Line ๐ฆ
The command line is made up of:
- The name of the requested verb,
- The identification of the transaction,
- The name of the endpoint(s) that are to execute the command (in notifications or restarts, the name of the endpoint(s) that is issuing the command),
- The protocol version.
These four items are encoded as strings of printable ASCII characters, separated by white spaces, i.e., the ASCII space (0x20) or tabulation (0x09) characters. It is RECOMMENDED to use exactly one ASCII space separator. However, MGCP entities MUST be able to parse messages with additional white space characters ๐
3.2.1.1. Coding of the Requested Verb ๐
The verbs that can be requested are encoded as four letter upper or lower case ASCII codes (comparisons SHALL be case insensitive) as defined in the following table:
-----------------------------
| Verb | Code |
|----------------------|------|
| EndpointConfiguration| EPCF |
| CreateConnection | CRCX |
| ModifyConnection | MDCX |
| DeleteConnection | DLCX |
| NotificationRequest | RQNT |
| Notify | NTFY |
| AuditEndpoint | AUEP |
| AuditConnection | AUCX |
| RestartInProgress | RSIP |
-----------------------------
The transaction identifier is encoded as a string of up to 9 decimal digits. In the command line, it comes right after the verb's code ๐
New verbs may be defined in further versions of the protocol. For experimentation, it may be necessary to use new verbs before they're sanctioned in a published version of this protocol. Experimental verbs MUST be identified by a four letter code starting with the letter X, such as XPER ๐งชโจ
3.2.1.2 Transaction Identifiers
okay so MGCP uses a transaction identifier to match commands up with their responses ๐ A gateway actually juggles two separate transaction identifier name spaces, and they're both main character energy ๐
- a transaction identifier name space for sending transactions, and
- a transaction identifier name space for receiving transactions.
At a minimum, transaction identifiers for commands sent to a given gateway MUST be unique for the maximum lifetime of the transactions within the collection of Call Agents that control that gateway ๐ฆ That way, no matter which Call Agent sent the command, the gateway can always spot a duplicate just by looking at the transaction identifier ๐ How the Call Agents coordinate those identifiers between themselves is outside the scope of this specification, though, so that's their own little group project ๐ซถ
Transaction identifiers for all commands sent from a given gateway MUST be unique for the maximum lifetime of the transactions, regardless of which Call Agent the command is sent to ๐ So a Call Agent can always catch a duplicate transaction coming from a gateway by checking the combo of the endpoint's domain name and the transaction identifier. Iconic ๐ญ
The transaction identifier is encoded as a string of up to nine decimal digits. In the command lines, it sits right after the verb, no gaps ๐ธ
Transaction identifiers have values between 1 and 999,999,999 (both included) ๐ They SHOULD NOT use any leading zeroes, although equality is based on the numerical value, so leading zeroes get ignored anyway. An MGCP entity MUST NOT reuse a transaction identifier any sooner than three minutes after the previous command that used it has completed โณ Not me waiting three whole minutes before recycling an ID ๐
3.2.1.3 Coding of the Endpoint Identifiers and Entity Names
The endpoint identifiers and entity names are encoded as case insensitive e-mail addresses, as defined in RFC 821 โจ There are a few syntax restrictions on the local part of the name, though. Both the local endpoint name part and the domain name part can each go up to 255 characters ๐ง The domain name tells you which system the endpoint is attached to, and the left side tells you which specific endpoint or entity lives on that system. It's giving address book energy ๐ฌ
Examples of such addresses are:
------------------------------------------------------------------
| hrd4/56@gw23.example.net | Circuit number 56 in |
| | interface "hrd4" of the Gateway |
| | 23 of the "Example" network |
| Call-agent@ca.example.net | Call Agent for the |
| | "example" network |
| Busy-signal@ann12.example.net| The "busy signal" virtual |
| | endpoint in the announcement |
| | server number 12. |
------------------------------------------------------------------
The name of a notified entity uses the same syntax, with the option of adding a port number, like this:
Call-agent@ca.example.net:5234
If the port number is left off the notified entity, the default MGCP Call Agent port (2727) MUST be used ๐ No guessing, bestie, just port 2727 ๐
3.2.1.4 Coding of the Protocol Version
The protocol version is coded as the keyword MGCP, followed by a white space and the version number. You can optionally tack a profile name on the end too ๐ The version number has a major version coded as a decimal number, a dot, and then a minor version coded as a decimal number. The version described in this document is version 1.0 ๐
The profile name, if there is one, is made of white-space separated strings of visible (printable) characters that run all the way to the end of the line. Profile names can be defined for user communities who want to apply restrictions or other profiling to MGCP ๐
In the initial messages, the version will be coded as:
MGCP 1.0
Now here's the important bit ๐จ An entity that receives a command with a protocol version it does not support MUST respond with an error. Error code 528 (incompatible protocol version) is RECOMMENDED for this ๐ And yes, this applies to unsupported profiles too, so a profile you don't recognise counts as a version you don't support ๐ญ๐ซถ
3.2.2 Parameter Lines ๐
okay so parameter lines are where the juicy details live ๐ Each one starts with a parameter name (usually just one or two characters), then a colon, then any optional white space, then the value. Here's the full lineup of what can show up in commands:
------------------------------------------------------------------
|Parameter name | Code | Parameter value |
|----------------------|------|------------------------------------|
|BearerInformation | B | See description (3.2.2.1). |
|CallId | C | See description (3.2.2.2). |
|Capabilities | A | See description (3.2.2.3). |
|ConnectionId | I | See description (3.2.2.5). |
|ConnectionMode | M | See description (3.2.2.6). |
|ConnectionParameters | P | See description (3.2.2.7). |
|DetectEvents | T | See description (3.2.2.8). |
|DigitMap | D | A text encoding of a digit map. |
|EventStates | ES | See description (3.2.2.9). |
|LocalConnectionOptions| L | See description (3.2.2.10). |
|MaxMGCPDatagram | MD | See description (3.2.2.11). |
|NotifiedEntity | N | An identifier, in RFC 821 format, |
| | | composed of an arbitrary string |
| | | and of the domain name of the |
| | | requesting entity, possibly com- |
| | | pleted by a port number, as in: |
| | | Call-agent@ca.example.net:5234 |
| | | See also Section 3.2.1.3. |
|ObservedEvents | O | See description (3.2.2.12). |
|PackageList | PL | See description (3.2.2.13). |
|QuarantineHandling | Q | See description (3.2.2.14). |
|ReasonCode | E | A string with a 3 digit integer |
| | | optionally followed by a set of |
| | | arbitrary characters (3.2.2.15). |
|RequestedEvents | R | See description (3.2.2.16). |
|RequestedInfo | F | See description (3.2.2.17). |
|RequestIdentifier | X | See description (3.2.2.18). |
|ResponseAck | K | See description (3.2.2.19). |
|RestartDelay | RD | A number of seconds, encoded as |
| | | a decimal number. |
|RestartMethod | RM | See description (3.2.2.20). |
|SecondConnectionId | I2 | Connection Id. |
|SecondEndpointId | Z2 | Endpoint Id. |
|SignalRequests | S | See description (3.2.2.21). |
|SpecificEndPointId | Z | An identifier, in RFC 821 format, |
| | | composed of an arbitrary string, |
| | | followed by an "@" followed by |
| | | the domain name of the gateway to |
| | | which this endpoint is attached. |
| | | See also Section 3.2.1.3. |
|----------------------|------|------------------------------------|
|RemoteConnection- | RC | Session Description. |
| Descriptor | | |
|LocalConnection- | LC | Session Description. |
| Descriptor | | |
------------------------------------------------------------------
not every parameter shows up in every command, so the next table is the cheat sheet for which ones are allowed where. M means mandatory, O means optional, and F means forbidden ๐ Unless otherwise specified, a parameter MUST NOT be present more than once, so no doubling up, bestie ๐ซ
------------------------------------------------------------------
| Parameter name | EP | CR | MD | DL | RQ | NT | AU | AU | RS |
| | CF | CX | CX | CX | NT | FY | EP | CX | IP |
|---------------------|----|----|----|----|----|----|----|----|----|
| BearerInformation | O*| O | O | O | O | F | F | F | F |
| CallId | F | M | M | O | F | F | F | F | F |
| Capabilities | F | F | F | F | F | F | F | F | F |
| ConnectionId | F | F | M | O | F | F | F | M | F |
| ConnectionMode | F | M | O | F | F | F | F | F | F |
| Connection- | F | F | F | O*| F | F | F | F | F |
| Parameters | | | | | | | | | |
| DetectEvents | F | O | O | O | O | F | F | F | F |
| DigitMap | F | O | O | O | O | F | F | F | F |
| EventStates | F | F | F | F | F | F | F | F | F |
| LocalConnection- | F | O | O | F | F | F | F | F | F |
| Options | | | | | | | | | |
| MaxMGCPDatagram | F | F | F | F | F | F | F | F | F |
| NotifiedEntity | F | O | O | O | O | O | F | F | F |
| ObservedEvents | F | F | F | F | F | M | F | F | F |
| PackageList | F | F | F | F | F | F | F | F | F |
| QuarantineHandling | F | O | O | O | O | F | F | F | F |
| ReasonCode | F | F | F | O | F | F | F | F | O |
| RequestedEvents | F | O | O | O | O*| F | F | F | F |
| RequestIdentifier | F | O*| O*| O*| M | M | F | F | F |
| RequestedInfo | F | F | F | F | F | F | O | M | F |
| ResponseAck | O | O | O | O | O | O | O | O | O |
| RestartDelay | F | F | F | F | F | F | F | F | O |
| RestartMethod | F | F | F | F | F | F | F | F | M |
| SecondConnectionId | F | F | F | F | F | F | F | F | F |
| SecondEndpointId | F | O | F | F | F | F | F | F | F |
| SignalRequests | F | O | O | O | O*| F | F | F | F |
| SpecificEndpointId | F | F | F | F | F | F | F | F | F |
|---------------------|----|----|----|----|----|----|----|----|----|
| RemoteConnection- | F | O | O | F | F | F | F | F | F |
| Descriptor | | | | | | | | | |
| LocalConnection- | F | F | F | F | F | F | F | F | F |
| Descriptor | | | | | | | | | |
------------------------------------------------------------------
Notes (*): the little stars matter, so read these closely โจ
- The BearerInformation parameter is only conditionally optional, as explained in Section 2.3.2 ๐
- The RequestIdentifier parameter is optional in connection creation, modification and deletion commands, but it becomes REQUIRED if the command contains an encapsulated notification request. so don't skip it when there's a notification tucked inside ๐ซถ
- The RequestedEvents and SignalRequests parameters are optional in the NotificationRequest. If you leave them out, the matching lists are treated as empty ๐ธ
- The ConnectionParameters parameter is only valid in a DeleteConnection request sent by the gateway ๐ฆ
okay now the extension situation ๐ Parameters can be extended in two ways:
- Package Extension Parameters (preferred) ๐
- Vendor Extension Parameters
Package Extension Parameters live inside packages, and honestly that's the iconic move because you get:
- a registration mechanism (IANA) for the package name ๐
- a separate name space for the parameters ๐ง
- a convenient grouping of the extensions ๐
- a simple way to check whether they're supported through auditing ๐ฅ
so yeah, the package route is the preferred one ๐
Vendor Extension Parameters are for when implementers need to experiment, like when they're building a brand new application of MGCP ๐งช Vendor extension parameters MUST be identified by names that start with the string "X-" or "X+", for example:
X-Flower: Daisy
"X+" names are critical parameter extensions ๐จ If an MGCP entity gets a critical extension it can't understand, it MUST refuse to execute the command. It SHOULD respond with error code 511 (unrecognized extension) ๐
"X-" names are non-critical parameter extensions ๐ซง If an MGCP entity gets one of those that it can't understand, it MUST simply ignore that parameter. No drama, just vibes ๐ท
Heads up: vendor extension parameters live in an unmanaged name space, which means two vendors could accidentally pick the same name and clash ๐ฌ So vendors are encouraged to put some vendor specific string, like the vendor name, into their extensions ๐
3.2.2.1 BearerInformation ๐ง
the bearer information values are a comma separated list of attributes. Each attribute is an attribute name, and it can optionally be followed by a colon and an attribute value ๐
the only attribute defined right now is "encoding" (code "e"), and it MUST have one of the values "A" (A-law) or "mu" (mu-law) ๐ Here's an example of how it looks:
B: e:mu
packages are allowed to extend the set of bearer information attributes too ๐ง
3.2.2.2 CallId ๐
the Call Identifier is a hexadecimal string, at most 32 characters long ๐ธ and here's the important bit: Call Identifiers get compared as strings, not as numbers, so "1F" and "1f" aren't a numerical match, they're a string comparison situation ๐
3.2.2.3 Capabilities โจ
okay so capabilities are how the endpoint tells the Call Agent what it can do when it gets audited ๐ซถ The encoding is basically based on the Local Connection Options encoding for the shared parameters, but with a different parameter line code, which is "A" ๐ On top of that, capabilities can also hold a list of supported packages and a list of supported modes. so extra โจ
here are the parameters you'll see:
A list of supported codecs. The following parameters apply to every codec in this list ๐ If some parameters, like silence suppression, only work with some codecs, then the gateway returns several Capability parameters, one for each set of codecs. ngl that's very organized of it ๐ง
Packetization Period: A range may be specified ๐ธ
Bandwidth: A range matching the range for packetization periods may be specified (assuming no silence suppression) ๐ If it's absent, the values get deduced from the codec type.
Echo Cancellation: "on" if echo cancellation is supported, "off" otherwise. The default is support ๐ฆ
Silence Suppression: "on" if silence suppression is supported for this codec, "off" otherwise. The default is support ๐
Gain Control: "0" if gain control is not supported. All other values indicate support for gain control. The default is support โญ
Type of Service: The value "0" indicates no support for type of service. All other values indicate support for type of service. The default is support ๐
Resource Reservation Service: This parameter indicates the reservation services that are supported, in addition to best effort ๐ The value "g" is encoded when the gateway supports both the guaranteed and the controlled load service. "cl" is encoded when only the controlled load service is supported. The default is "best effort" ๐
Encryption Key: Encoding any value indicates support for encryption. The default is no support, which is implied by omitting the parameter ๐
Type of network: The keyword "nt", followed by a colon and a semicolon separated list of supported network types. This parameter is optional ๐ซง
Packages: The packages supported by the endpoint are encoded as the keyword "v", followed by a colon and a character string. If a list of values is specified, the values are separated by a semicolon. The first value specified is the default package for the endpoint ๐
Modes: The modes supported by this endpoint are encoded as the keyword "m", followed by a colon and a semicolon-separated list of supported connection modes for this endpoint ๐ฆ
lack of support for a capability can also be shown by leaving that parameter out of the capability set. no drama, just absence ๐
here's an example capability:
A: a:PCMU;G728, p:10-100, e:on, s:off, t:1, v:L,
m:sendonly;recvonly;sendrecv;inactive
the line break up there is only there so it fits on the screen. it is not allowed in a real implementation, so don't copy it like that ๐ญ
if you need to return multiple capabilities, each one gets its own capability line ๐
Local Connection Options can be extended, so the list of capability parameters can be extended too ๐ง individual extensions can define how they get reported as capabilities. if an extension doesn't provide that definition, these defaults apply:
- Package Extension attributes: the individual attributes are not reported. Instead, just the name of the package gets reported in the list of supported packages.
- Vendor Extension attributes: the name of the attribute is reported without any value.
- Other Extension attributes: the name of the attribute is reported without any value.
3.2.2.4 Coding of Event Names ๐ฆ
event names are made of an optional package name, separated by a slash (/) from the actual event name (see Section 2.1.7) ๐
The wildcard character star ("*") can be use to refer to all packages. The event name can optionally be followed by an at sign (@) and the identifier of a connection (which can use a wildcard) where the event should be observed. Event names get used in the RequestedEvents, SignalRequests, ObservedEvents, DetectEvents, and EventStates parameters ๐ธ
events and signals can be qualified by parameters that are defined for the event or signal. Those parameters may be enclosed in double-quotes. some parameters MUST be enclosed in double-quotes because of syntax restrictions, so those ones are required to be quoted ๐ญ when they are, they're UTF-8 encoded [20] โจ
the parameter name "!" (exclamation point) is reserved for future use, for both events and signals ๐
every signal has one of these signal-types: On/Off (OO), Time-out (TO), or Brief (BR). (These signal types are specified in the package definitions, and they are not present in the messages.) On/Off signals can be parameterized with a "+" to turn the signal on, or a "-" to turn it off. If an on/off signal is not parameterized, it gets turned on. Both of these will turn the vmwi signal (from the line package "L") on:
L/vmwi(+)
L/vmwi
besides "!", "+" and "-", the signal parameter "to" is reserved too ๐ง It can be used with Time-Out signals to override the default time-out value for the current request. the value is a decimal number in milliseconds. The individual signal and/or package definition SHOULD indicate whether this parameter is supported for one or more TO signals in the package. If it's not indicated, TO signals in package version zero are assumed to not support it, and TO signals in package versions one or higher are assumed to support it ๐ By default, a supplied time-out value MAY be rounded to the nearest non-zero value divisible by 1000, which means a whole second. The individual signal and/or package definition may define other rounding rules. All new package and TO signal definitions are strongly encouraged to support the "to" signal parameter ๐ซถ
here's how you'd use "to" to apply a signal for 6 seconds:
L/rg(to=6000)
L/rg(to(6000))
here are some event name examples:
-----------------------------------------------------------
| L/hu | on-hook transition, in the line package |
| F/0 | digit 0 in the MF package |
| hf | Hook-flash, assuming that the line package|
| | is the default package for the endpoint. |
| G/rt@0A3F58 | Ring back signal on connection "0A3F58" |
-----------------------------------------------------------
and then there's range and wildcard notation for events ๐ you can use it instead of individual names in the RequestedEvents and DetectEvents parameters. The event code "all" is reserved and refers to all events or signals in a package. The star sign ("*") can be used to denote "all connections", and the dollar sign ("$") can be used to denote the "current" connection (see Section 2.1.7 for details) โจ
these examples show how those notations look:
---------------------------------------------------------
| M/[0-9] | Digits 0 to 9 in the MF package. |
| hf | Hook-flash, assuming that the line package|
| | is a default package for the endpoint. |
| [0-9*#A-D]| All digits and letters in the DTMF |
| | packages (default for endpoint). |
| T/all | All events in the trunk package. |
| R/qa@* | The quality alert event on all |
| | connections. |
| G/rt@$ | Ringback on current connection. |
---------------------------------------------------------
3.2.2.5 ConnectionId ๐
the Connection Identifier is encoded as a hexadecimal string, at most 32 characters long ๐ Connection Identifiers get compared as strings, not as numerical values, so no math on them, bestie ๐ โโ๏ธ
3.2.2.6 ConnectionMode ๐
the connection mode describes how the connection operates ๐ธ The possible values are:
--------------------------------------------------------
| Mode | Meaning |
|-------------|------------------------------------------|
| M: sendonly | The gateway should only send packets |
| M: recvonly | The gateway should only receive packets |
| M: sendrecv | The gateway should send |
| | and receive packets |
| M: confrnce | The gateway should place |
| | the connection in conference mode |
| M: inactive | The gateway should neither |
| | send nor receive packets |
| M: loopback | The gateway should place |
| | the circuit in loopback mode. |
| M: conttest | The gateway should place |
| | the circuit in test mode. |
| M: netwloop | The gateway should place |
| | the connection in network loopback mode.|
| M: netwtest | The gateway should place the connection |
| | in network continuity test mode. |
--------------------------------------------------------
note that no matter the connection mode, signals applied to the connection will still result in packets being sent (see Section 2.3.1) ๐ญ๐ซถ
the set of connection modes can be extended through packages ๐
3.2.2.7 ConnectionParameters
okay bestie, connection parameters are like a little stats card ๐๐ They get encoded as a string of type and value pairs. The type is either a two-letter identifier of the parameter or an extension type, and the value is a decimal integer. The type gets separated from the value by an = sign, and each parameter gets separated from the next by a comma ๐ Connection parameter values can hold up to nine digits. Once the max is hit, the counter just stops updating. It doesn't wrap or overflow, no drama ๐
โโ๏ธโจ
the parameter types are listed in this table ๐ฆ
-----------------------------------------------------------------
| Connection parameter| Code | Connection parameter |
| name | | value |
|---------------------|------|------------------------------------|
| Packets sent | PS | The number of packets that |
| | | were sent on the connection. |
| Octets sent | OS | The number of octets that |
| | | were sent on the connection. |
| Packets received | PR | The number of packets that |
| | | were received on the connection. |
| Octets received | OR | The number of octets that |
| | | were received on the connection. |
| Packets lost | PL | The number of packets that |
| | | were lost on the connection |
| | | as deduced from gaps in the |
| | | RTP sequence number. |
| Jitter | JI | The average inter-packet arrival |
| | | jitter, in milliseconds, |
| | | expressed as an integer number. |
| Latency | LA | Average latency, in milliseconds, |
| | | expressed as an integer number. |
-----------------------------------------------------------------
so the set of connection parameters can be extended in two different ways ๐
- Package Extension Parameters (preferred) ๐
- Vendor Extension Parameters
Package Extension Connection Parameters live in packages, and packages come with some seriously iconic perks ๐
- A registration mechanism (IANA) for the package name.
- A separate name space for the parameters.
- A convenient grouping of the extensions.
- A simple way to determine support for them through auditing.
the package extension mechanism is the preferred extension method, bestie ๐ซถ
vendor extension parameter names are made up of the string "X-" followed by an extension parameter name that has two or more letters ๐
call agents that receive unrecognized package or vendor connection parameter extensions SHALL silently ignore these parameters. no drama, just vibes ๐
an example of connection parameter encoding looks like this ๐ง
P: PS=1245, OS=62345, PR=0, OR=0, PL=0, JI=0, LA=48
3.2.2.8 DetectEvents
the DetectEvents parameter is encoded as a comma separated list of events (see Section 3.2.2.4) ๐ฅ for example:
T: L/hu,L/hd,L/hf,D/[0-9#*]
it should be noted, though, that no actions can be associated with the events. event parameters may be provided, tho ๐
3.2.2.9 EventStates
the EventStates parameter is also encoded as a comma separated list of events (see Section 3.2.2.4) ๐ธ for example:
ES: L/hu
same energy here: it should be noted that no actions can be associated with the events, however event parameters may be provided โจ
3.2.2.10 LocalConnectionOptions
the local connection options describe the operational parameters that the Call Agent gives the gateway in connection handling commands ๐ these include:
- The allowed codec(s), encoded as the keyword "a", followed by a colon and a character string. If the Call Agent specifies a list of values, those values get separated by a semicolon. For RTP, audio codecs SHALL be specified by using encoding names defined in the RTP AV Profile [4] or its replacement, or by encoding names registered with the IANA. Non-audio media registered as a MIME type MUST use the "<MIME type>/<MIME subtype>" form, as in "image/t38" ๐ฆ
- The packetization period in milliseconds, encoded as the keyword "p", followed by a colon and a decimal number. If the Call Agent specifies a range of values, the range gets specified as two decimal numbers separated by a hyphen (as specified for the "ptime" parameter for SDP) โฑ๏ธ
- The bandwidth in kilobits per second (1000 bits per second), encoded as the keyword "b", followed by a colon and a decimal number. If the Call Agent specifies a range of values, the range gets specified as two decimal numbers separated by a hyphen ๐ถ
- The type of service parameter, encoded as the keyword "t", followed by a colon and the value encoded as two hexadecimal digits. When the connection is sent over an IP network, the parameters encode the 8-bit type of service value parameter of the IP header (a.k.a. DiffServ field). The left-most "bit" in the parameter corresponds to the least significant bit in the IP header ๐ง
- The echo cancellation parameter, encoded as the keyword "e", followed by a colon and the value "on" or "off" ๐
- The gain control parameter, encoded as the keyword "gc", followed by a colon and a value that can be either the keyword "auto" or a decimal number (positive or negative) representing the number of decibels of gain ๐๏ธ
- The silence suppression parameter, encoded as the keyword "s", followed by a colon and the value "on" or "off" ๐คซ
- The resource reservation parameter, encoded as the keyword "r", followed by a colon and the value "g" (guaranteed service), "cl" (controlled load) or "be" (best effort) ๐ธ
- The encryption key, encoded as the keyword "k" followed by a colon and a key specification, as defined for the parameter "K" in SDP (RFC 2327) ๐
- The type of network, encoded as the keyword "nt" followed by a colon and the type of network encoded as the keyword "IN" (internet), "ATM", "LOCAL" (for a local connection), or possibly another type of network registered with the IANA as per SDP (RFC 2327) ๐
- The resource reservation parameter, encoded as the keyword "r", followed by a colon and the value "g" (guaranteed service), "cl" (controlled load) or "be" (best effort) ๐ธ
the encoding of the first three attributes, when they're present, will be compatible with the SDP and RTP profiles ๐ each attribute is optional, fr. when several attributes show up, they get separated by a comma.
examples of local connection options are ๐
L: p:10, a:PCMU
L: p:10, a:G726-32
L: p:10-20, b:64
L: b:32-64, e:off
the set of Local Connection Options attributes can be extended in three different ways ๐
- Package Extension attributes (preferred) ๐
- Vendor Extension attributes
- Other Extension attributes
Package Extension Local Connection Options attributes are defined in packages, which give you these benefits โจ
- A registration mechanism (IANA) for the package name.
- A separate name space for the attributes.
- A convenient grouping of the extensions.
- A simple way to determine support for them through auditing.
the package extension mechanism is the preferred extension method ๐ซถ
vendor extension attributes are made of an attribute name, possibly followed by a colon and an attribute value. the attribute name MUST start with the two characters "x+", for a mandatory extension, or "x-", for a non-mandatory extension. if a gateway gets a mandatory extension attribute it doesn't recognize, it MUST reject the command (error code 525 - unknown extension in LocalConnectionOptions, is RECOMMENDED) ๐ โโ๏ธ
ngl, this is the part where things can get messy ๐ vendor extension attributes use an unmanaged name space, which means there's a potential for name clashing. vendors are consequently encouraged to include some vendor specific string, e.g., vendor name, in their vendor extensions ๐ท๏ธ
finally, for backwards compatibility with some existing implementations, MGCP allows for other extension attributes too (see grammar in Appendix A) ๐ฐ๏ธ note tho that these attribute extensions do not provide the package extension attribute benefits, so using this mechanism for new extensions is discouraged ๐
3.2.2.11 MaxMGCPDatagram
the MaxMGCPDatagram can only be used for auditing, i.e., it's a valid RequestedInfo code and can be provided as a response parameter ๐
in responses, the MaxMGCPDatagram value is encoded as a string of up to nine decimal digits. leading zeroes are not permitted ๐ซ this example shows it in action ๐
MD: 8100
3.2.2.12 ObservedEvents
the observed events parameter gives you the list of events that have been observed ๐ the event codes are the same as the ones used in the NotificationRequest. events accumulated according to the digit map may be grouped in a single string, but honestly that practice is discouraged ๐ they SHOULD be reported as lists of isolated events if other events were detected during the digit accumulation. examples of observed events:
O: L/hu
O: D/8295555T
O: D/8,D/2,D/9,D/5,D/5,L/hf,D/5,D/5,D/T
O: L/hf, L/hf, L/hu
3.2.2.13 PackageList
the Package List can only be used for auditing, i.e., it's a valid RequestedInfo code and can be provided as a response parameter ๐
the response parameter consists of a comma separated list of packages supported. the first package returned in the list is the default package ๐ each package in the list is the package name followed by a colon and the highest version number of the package supported ๐ข
an example of a package list is ๐
PL: L:1,G:1,D:0,FOO:2,T:1
note that for backwards compatibility, support for this parameter is OPTIONAL ๐ซถ
3.2.2.14 QuarantineHandling
the quarantine handling parameter contains a list of comma separated keywords ๐
- The keyword "process" or "discard" to indicate the treatment of quarantined and observed events. If neither "process" or "discard" is present, "process" is assumed.
- The keyword "step" or "loop" to indicate whether at most one notification per NotificationRequest is allowed, or whether multiple notifications per NotificationRequest are allowed. If neither "step" nor "loop" is present, "step" is assumed. ๐
the following values are valid examples ๐
Q: loop
Q: process
Q: loop,discard
3.2.2.15 ReasonCode
reason codes are three-digit numeric values ๐ข the reason code can optionally be followed by a white space and commentary, e.g. ๐ฌ
E: 900 Endpoint malfunctioning
a list of reason codes can be found in Section 2.5 ๐
and the set of reason codes can be extended through packages ๐งโจ
3.2.2.16 RequestedEvents
okay bestie, so the RequestedEvents parameter is the list of events you're asking the gateway to keep an eye out for ๐โจ the event codes are explained back in Section 3.2.2.4, so go check that if you need the deets ๐
every event can get qualified by a requested action, or by a whole list of actions ๐ when you do specify actions, they go in a list of keywords, wrapped in parentheses and separated by commas. the action codes are:
-------------------------------------
| Action | Code |
|------------------------------|------|
| Notify immediately | N |
| Accumulate | A |
| Treat according to digit map | D |
| Swap | S |
| Ignore | I |
| Keep Signal(s) active | K |
| Embedded Notification Request| E |
-------------------------------------
when no action is specified, the default is to notify the event, so ft and ft(N) are literally the same thing ๐ฆ events that aren't listed just get ignored (unless they're persistent, which is its own whole vibe ๐ธ)
the digit-map action SHOULD only be specified for the digits, letters and interdigit timers in packages that define the encoding of digits, letters, and timers (including extension digit map letters). ๐ง
the requested events list lives on a single line, with event/action groups separated by commas. some examples:
R: L/hu(N), L/hf(S,N)
R: L/hu(N), D/[0-9#T](D)
now the Embedded Notification Request action is where it gets iconic ๐ญ the embedded notification request parameters are encoded as a list of up to three parameter groups separated by commas. each group starts with a one letter identifier, followed by a list of parameters in parentheses. the first optional group, letter "R", is the embedded RequestedEvents value. the second optional group, letter "S", is the embedded SignalRequests value. the third optional group, letter "D", is the embedded DigitMap value. (ngl some existing implementations and profiles encode these three in a different order. implementers are encouraged to accept those encodings, but they SHOULD NOT generate them. ๐)
if the RequestedEvents parameter isn't present, it gets set to a null value. if the SignalRequests parameter isn't present, it gets set to a null value. if the DigitMap is absent, the current value MUST be used. here are some valid embedded requests:
R: L/hd(E(R(D/[0-9#T](D),L/hu(N)),S(L/dl),D([0-9].[#T])))
R: L/hd(E(R(D/[0-9#T](D),L/hu(N)),S(L/dl)))
some events can be qualified by extra event parameters too ๐ those go in commas inside parentheses. event parameters may be wrapped in double-quotes (some of them MUST be, because of syntax rules, and then the quoted string itself is UTF-8 encoded ๐ซถ). check Section 3.2.2.4 for more on event parameters.
here's the foobar event with an event parameter "epar":
R: X/foobar(N)(epar=2)
notice the Action got included even though it's the default Notify action. that's required by the grammar, bestie ๐
3.2.2.17 RequestedInfo
the RequestedInfo parameter is a comma separated list of parameter codes, as defined in Section 3.2.2. for example, if you want to audit the NotifiedEntity, RequestIdentifier, RequestedEvents, SignalRequests, DigitMap, QuarantineHandling and DetectEvents values, the RequestedInfo value will be:
F: N,X,R,S,D,Q,T
extension parameters can be audited too, generally speaking ๐ the individual extension defines how the auditing works.
the capabilities request in the AuditEndPoint command is encoded with the parameter code "A", like this:
F: A
3.2.2.18 RequestIdentifier
the request identifier is what links a Notify command to the NotificationRequest that set it off ๐ it's a hexadecimal string, at most 32 characters long. RequestIdentifiers get compared as strings, not as numerical values ๐ฅ the string "0" is reserved for reporting persistent events when a NotificationRequest hasn't been received yet after a restart ๐ธ
3.2.2.19 ResponseAck
the response acknowledgement parameter is how you manage the "at-most-once" facility from Section 3.5 ๐ฆ it holds a comma separated list of "confirmed transaction-id ranges".
each "confirmed transaction-id range" is either one decimal number (when the range covers exactly one transaction) or two decimal numbers joined by a single hyphen, giving the lower and higher transaction identifiers in the range โจ
an example response acknowledgement:
K: 6234-6255, 6257, 19030-19044
3.2.2.20 RestartMethod
the RestartMethod parameter is one of the keywords "graceful", "forced", "restart", "disconnected" or "cancel-graceful" ๐ง for example:
RM: restart
packages can extend the set of restart methods, so it's not locked in ๐
3.2.2.21 SignalRequests
the SignalRequests parameter gives the name of the signal(s) that have been requested. each signal is identified by a name, as described in Section 3.2.2.4 ๐
some signals, like announcement or ADSI display, can be qualified with extra parameters, such as:
- the name and parameters of the announcement,
- the string that should be displayed.
those parameters get separated by commas and wrapped in parentheses, like this:
S: L/adsi("123456 Francois Gerard")
S: A/ann(http://ann.example.net/no-such-number.au, 1234567)
when a quoted-string is provided, the string itself is UTF-8 encoded [20] ๐
when several signals are requested, their codes are separated by a comma:
S: L/adsi("123456 Your friend"), L/rg
check Section 3.2.2.4 for more on signal parameters, iykyk ๐โจ
3.3 Format of response headers โจ
okay so the response header is basically a response line, and then optionally some headers that carry the response parameters bestie ๐
here's a lil example:
200 1203 OK
the response line starts with the response code, which is a three digit numeric value ๐ข then comes a white space and the transaction identifier. response codes defined in packages (8xx) are followed by a white space, a slash (/) and the package name ๐ฆ every response code can also have optional commentary after a white space, so you can add a little note if you want ๐ฌ
now the parameter table, which is giving everything ๐ it tells you whether each parameter is mandatory (M), optional (O) or forbidden (F), depending on which command triggered the response. unless something else is specified, a parameter MUST NOT be present more than once ๐ โโ๏ธ and the table only shows the defaults for responses that didn't define any other behaviour. if a response comes in with a parameter that's either not understood or marked as forbidden, the offending parameter(s) MUST simply be ignored ๐ซถ
------------------------------------------------------------------
| Parameter name | EP | CR | MD | DL | RQ | NT | AU | AU | RS |
| | CF | CX | CX | CX | NT | FY | EP | CX | IP |
|---------------------|----|----|----|----|----|----|----|----|----|
| BearerInformation | F | F | F | F | F | F | O | F | F |
| CallId | F | F | F | F | F | F | F | O | F |
| Capabilities | F | F | F | F | F | F | O*| F | F |
| ConnectionId | F | O*| F | F | F | F | O*| F | F |
| ConnectionMode | F | F | F | F | F | F | F | O | F |
| Connection- | F | F | F | F | F | F | F | O | F |
| Parameters | | | | | | | | | |
| DetectEvents | F | F | F | F | F | F | O | F | F |
| DigitMap | F | F | F | F | F | F | O | F | F |
| EventStates | F | F | F | F | F | F | O | F | F |
| LocalConnection- | F | F | F | F | F | F | F | O | F |
| Options | | | | | | | | | |
| MaxMGCPDatagram | F | F | F | F | F | F | O | F | F |
| NotifiedEntity | F | F | F | F | F | F | O | O | O |
| ObservedEvents | F | F | F | F | F | F | O | F | F |
| QuarantineHandling | F | F | F | F | F | F | O | F | F |
| PackageList | O*| O*| O*| O*| O*| O*| O | O*| O*|
| ReasonCode | F | F | F | F | F | F | O | F | F |
| RequestIdentifier | F | F | F | F | F | F | O | F | F |
| ResponseAck | O*| O*| O*| O*| O*| O*| O*| O*| O*|
| RestartDelay | F | F | F | F | F | F | O | F | F |
| RestartMethod | F | F | F | F | F | F | O | F | F |
| RequestedEvents | F | F | F | F | F | F | O | F | F |
| RequestedInfo | F | F | F | F | F | F | F | F | F |
| SecondConnectionId | F | O | F | F | F | F | F | F | F |
| SecondEndpointId | F | O | F | F | F | F | F | F | F |
| SignalRequests | F | F | F | F | F | F | O | F | F |
| SpecificEndpointId | F | O | F | F | F | F | O*| F | F |
|---------------------|----|----|----|----|----|----|----|----|----|
| LocalConnection- | F | O*| O | F | F | F | F | O*| F |
| Descriptor | | | | | | | | | |
| RemoteConnection- | F | F | F | F | F | F | F | O*| F |
| Descriptor | | | | | | | | | |
------------------------------------------------------------------
notes (*) time!! ๐ธ
- the PackageList parameter is only allowed with return code 518 (unsupported package) ๐ฆ, except for AuditEndpoint, where it can also come back if audited ๐
- the ResponseAck parameter MUST NOT be used with any other responses than a final response issued after a provisional response for the transaction in question ๐ซ in that case, the presence of the ResponseAck parameter SHOULD trigger a Response Acknowledgement, but any ResponseAck values provided will be ignored ๐งพ
- for a CreateConnection message, the response line is followed by a Connection-Id parameter and a LocalConnectionDescriptor ๐ it may also be followed by a Specific-Endpoint-Id parameter, if the creation request went to a wildcarded Endpoint-Id ๐ the table marks Connection-Id and LocalConnectionDescriptor as optional, but honestly they're mandatory with all positive responses (when a connection got created) and forbidden when the response is negative and no connection was created ๐ค
- a LocalConnectionDescriptor MUST be transmitted with a positive response (code 200) to a CreateConnection ๐ it MUST also be transmitted in response to a ModifyConnection command, if the modification resulted in a change to the session parameters ๐ the LocalConnectionDescriptor is encoded as a "session description", as defined in section 3.4 ๐ and it's separated from the response header by an empty line โจ
- Connection-Parameters are only valid in a response to a non-wildcarded DeleteConnection command sent by the Call Agent ๐
- multiple ConnectionId, SpecificEndpointId, and Capabilities parameters may be present in the response to an AuditEndpoint command ๐ง
- when several session descriptors are encoded in the same response, they go one after the other, separated by an empty line ๐ this happens for example when the response to an audit connection request carries both a local and a remote session description, like this:
200 1203 OK
C: A3C47F21456789F0
N: [128.96.41.12]
L: p:10, a:PCMU;G726-32
M: sendrecv
P: PS=1245, OS=62345, PR=780, OR=45123, PL=10, JI=27,LA=48
v=0
o=- 25678 753849 IN IP4 128.96.41.1
s=-
c=IN IP4 128.96.41.1
t=0 0
m=audio 1296 RTP/AVP 0
v=0
o=- 33343 346463 IN IP4 128.96.63.25
s=-
c=IN IP4 128.96.63.25
t=0 0
m=audio 1296 RTP/AVP 0 96
a=rtpmap:96 G726-32/8000
in this example, according to the SDP syntax, each description starts with a "version" line, (v=...) ๐ฆ the local description is always sent before the remote description ๐ซถ and if a connection descriptor is requested but doesn't exist for the connection being audited, that descriptor shows up with only the SDP protocol version field ๐
the response parameters get described for each command in the following bits, so let's go ๐โโ๏ธ๐จ
3.3.1 CreateConnection Response
okay so for a CreateConnection message, the response line is followed by a Connection-Id parameter on a successful response (code 200) ๐ a LocalConnectionDescriptor also gets sent with a positive response ๐ก it's encoded as a "session description", as defined by SDP (RFC 2327), and separated from the response header by an empty line, like this:
200 1204 OK
I: FDE234C8
v=0
o=- 25678 753849 IN IP4 128.96.41.1
s=-
c=IN IP4 128.96.41.1
t=0 0
m=audio 3456 RTP/AVP 96
a=rtpmap:96 G726-32/8000
if a provisional response was sent earlier, the final response SHOULD furthermore contain the Response Acknowledgement parameter ๐งพ (final responses from entities following this specification will include the parameter, but older RFC 2705 implementations MAY not ๐ฐ๏ธ):
200 1204 OK
K:
I: FDE234C8
v=0
o=- 25678 753849 IN IP4 128.96.41.1
s=-
c=IN IP4 128.96.41.1
t=0 0
m=audio 3456 RTP/AVP 96
a=rtpmap:96 G726-32/8000
the final response SHOULD then be acknowledged by a Response Acknowledgement ๐
000 1204
3.3.2 ModifyConnection Response
for a successful ModifyConnection message, the response line is followed by a LocalConnectionDescriptor, but only if the modification actually changed the session parameters ๐๏ธ (like, changing only the mode of a connection does NOT touch the session parameters, so no descriptor, bestie ๐ โโ๏ธ). the LocalConnectionDescriptor is encoded as a "session description", as defined by SDP, and it's separated from the response header by an empty line โจ
200 1207 OK
v=0
o=- 25678 753849 IN IP4 128.96.41.1
s=-
c=IN IP4 128.96.41.1
t=0 0
m=audio 3456 RTP/AVP 0
if a provisional response was issued before, the final response SHOULD furthermore contain the Response Acknowledgement parameter, like so ๐
200 1207 OK
K:
and the final response SHOULD then be acknowledged by a Response Acknowledgement ๐ซถ
000 1207 OK
3.3.3 DeleteConnection Response
depending on which variant of the DeleteConnection message you sent, the response line may be followed by a Connection Parameters parameter line, as defined in Section 3.2.2.7 ๐
250 1210 OK
P: PS=1245, OS=62345, PR=780, OR=45123, PL=10, JI=27, LA=48
3.3.4 NotificationRequest Response
a successful NotificationRequest response doesn't include any additional response parameters ๐ clean and simple, iconic โจ
3.3.5 Notify Response
a successful Notify response doesn't include any additional response parameters either ๐ same energy, no extras ๐ง
3.3.6 AuditEndpoint Response
in the case of a successful AuditEndPoint, the response line may be followed by info for each of the parameters you requested, with each parameter on its own line ๐ parameters that don't have a current value (like a digit map) still get provided, just with an empty value ๐ซ each local endpoint name "expanded" by a wildcard character shows up on a separate line using the "SpecificEndPointId" parameter code, e.g.:
200 1200 OK
Z: aaln/1@rgw.whatever.net
Z: aaln/2@rgw.whatever.net
when connection identifiers are audited and there are multiple connections on the endpoint, a comma-separated list of connection identifiers SHOULD be returned ๐
200 1200 OK
I: FDE234C8, DFE233D1
or you can get multiple connection id parameter lines instead ๐ช the two forms should not be mixed, although doing so isn't an error, just messy ๐
when capabilities are audited, the response may include multiple capabilities parameter lines, like this ๐ง
200 1200 OK
A: a:PCMU;G728, p:10-100, e:on, s:off, t:1, v:L,
m:sendonly;recvonly;sendrecv;inactive
A: a:G729, p:30-90, e:on, s:on, t:1, v:L,
m:sendonly;recvonly;sendrecv;inactive;confrnce
note: the carriage return for Capabilities shown above is only there for formatting reasons ๐ it is NOT permissible in a real command encoding ๐ซ
3.3.7. AuditConnection Response โจ
okay so if an AuditConnection works, the response can come with extra info, one line for each parameter you asked for ๐ Even if a parameter doesn't have a value yet, it still shows up, so nothing gets dropped ๐ซถ The connection descriptors always come last, and each one gets its own empty line before it, like this:
200 1203 OK
C: A3C47F21456789F0
N: [128.96.41.12]
L: p:10, a:PCMU;G728
M: sendrecv
P: PS=622, OS=31172, PR=390, OR=22561, PL=5, JI=29, LA=50
v=0
o=- 4723891 7428910 IN IP4 128.96.63.25
s=-
c=IN IP4 128.96.63.25
t=0 0
m=audio 1296 RTP/AVP 96
a=rtpmap:96 G726-32/8000
If you get both a local and a remote connection descriptor, the local one goes first ๐ธ And if you asked for a connection descriptor that doesn't exist for the connection being audited, it still shows up, but with only the SDP protocol version field (v=0), like this:
200 1203 OK
v=0
3.3.8. RestartInProgress Response ๐ฆ
A successful RestartInProgress response may include a NotifiedEntity parameter, but that's it for extra response parameters. No other additions, bestie ๐
Also, a 521 response to a RestartInProgress MUST include a NotifiedEntity parameter with the name of another Call Agent to contact. That's for when the first Call Agent redirects the endpoint to a different Call Agent, like this:
521 1204 Redirect
N: CA-1@whatever.net
3.4. Encoding of the Session Description (SDP) ๐
The session description (SDP) gets encoded following the session description protocol, SDP. MGCP implementations are REQUIRED to be fully capable of parsing any conformant SDP message, and they MUST send session descriptions that strictly conform to the SDP standard. No wiggle room there ๐ญ
You can find the general description and explanation of SDP parameters in RFC 2327 (or its successor). The big thing to notice is that the
- Origin (
o=), - Session Name (
s=), and - Time active (
t=)
fields are all mandatory in RFC 2327. They're not super useful to MGCP, but they MUST still be provided in conformance with RFC 2327 anyway ๐ Below are the suggested values for each field. You should still check RFC 2327 (or its successor) for the details, though ๐
Origin:
o = <username> <session id> <version> <network type> <address type>
<address>
- The username SHOULD be set to hyphen (
-). - The session id is RECOMMENDED to be an NTP timestamp, as suggested in RFC 2327.
- The version is a version number that MUST increment with each change to the SDP. A counter starting at zero, or an NTP timestamp as suggested in RFC 2327, is RECOMMENDED.
- The network type defines the type of network. For RTP sessions, the network type SHOULD be
IN. - The address type defines the type of address. For RTP sessions, the address type SHOULD be
IP4(orIP6). - The address SHOULD be the same address as provided in the connection information (
c=) field.
Session Name:
s = <session name>
The session name should be hyphen (-).
Time active:
t = <start time> <stop time>
- The start time may be set to zero.
- The stop time should be set to zero.
You can ignore each of the three fields when you receive them โจ
To keep up with MGCP's extensibility principles, implementations are encouraged to support the PINT "a=require" attribute. Check out RFC 2848 for the full scoop ๐
The actual usage of SDP depends on the kind of session being set up. Below we describe how SDP gets used for an audio service using the RTP/AVP profile [4], and for the LOCAL interconnect defined in this document. If anything below conflicts with SDP (RFC 2327 or its successor), the SDP specification takes precedence, so go with that one ๐
3.4.1. Usage of SDP for an Audio Service ๐ง
In a telephony gateway, we only have to describe sessions that use exactly one media type, audio. Using SDP for this is straightforward and it's described in detail in RFC 2327 โจ
Here's an example of an RFC 2327 conformant session description for an audio connection:
v=0
o=- A7453949499 0 IN IP4 128.96.41.1
s=-
c=IN IP4 128.96.41.1
t=0 0
m=audio 3456 RTP/AVP 0 96
a=rtpmap:96 G726-32/8000
3.4.2. Usage of SDP for LOCAL Connections ๐ง
When MGCP sets up internal connections inside a single gateway, the SDP format encodes the parameters of that connection. The connection and media parameters get used like this:
- The connection parameter (
c=) specifies that the connection is local, using the keywordLOCALas the network type, the keywordEPN(endpoint name) as the address type, and the local name of the endpoint as the connection-address. - The
m=audioparameter specifies a port number, which is always set to 0, the type of protocol, which is always the keyword LOCAL, and the type of encoding, using the same conventions as the RTP AVP profile (RTP payload numbers). The type of encoding should normally be set to 0 (PCMU).
A session-level attribute identifying the connection MAY furthermore be present. This lets endpoints support multiple LOCAL connections. Using this attribute is OPTIONAL, and it's honestly unnecessary for endpoints that only support a single LOCAL connection ๐ The attribute is defined like this:
a=MGCPlocalcx:<ConnectionID>
The MGCP Local Connection attribute is a session-level-only, case-insensitive attribute. It identifies the MGCP LOCAL connection, on the endpoint named in the connection information, that the SDP applies to. The ConnectionId is a hexadecimal string containing at most 32 characters. The ConnectionId itself is case-insensitive. The MGCP Local Connection attribute is not subject to the charset attribute ๐
Here's an example of a LOCAL session description:
v=0
o=- A7453949499 0 LOCAL EPN X35V3+A4/13
s=-
c=LOCAL EPN X35V3+A4/13
t=0 0
a=MGCPlocalcx:FDE234C8
m=audio 0 LOCAL 0
Heads up: the MGCP Local Connection attribute gets specified at the session level, and it could've been left out if you only support a single LOCAL connection per endpoint ๐
3.5. Transmission over UDP ๐ฎ
MGCP messages get sent over UDP. Commands go to one of the IP addresses defined in the DNS for the specified endpoint. Responses get sent back to the source address (that's the IP address and UDP port number) of the commands. The response may or may not arrive from the same address the command was sent to, so don't be shocked if it doesn't ๐ญ
When no port is specified for the endpoint, the commands MUST by default be sent:
- by the Call Agents, to the default MGCP port for gateways, 2427.
- by the Gateways, to the default MGCP port for Call Agents, 2727.
3.5.1. Providing the At-Most-Once Functionality ๐ฅ
MGCP messages are carried over UDP, so they can get lost. If a response doesn't show up in time, commands get retransmitted. Most MGCP commands are not idempotent. The gateway's state would get unpredictable if, say, CreateConnection commands ran several times. So the transmission procedures MUST provide an "at-most-once" functionality. Non-negotiable, periodt ๐
MGCP entities are expected to keep two lists in memory: one of the responses they sent for recent transactions, and one of the transactions that are currently being executed. The numerical value of the transaction identifiers in incoming commands gets compared to the transaction identifiers of the recent responses. If there's a match, the MGCP entity doesn't run the transaction again. It just resends the response. The remaining commands get compared to the list of current transactions, meaning transactions received earlier that haven't finished executing yet. If there's a match there, the MGCP entity doesn't run the transaction again either, but a provisional response (Section 3.5.5) SHOULD be issued to acknowledge receipt of the command โจ
The procedure uses a long timer value, called T-HIST below. The timer MUST be set larger than the maximum duration of a transaction. That duration MUST take into account the maximum number of repetitions, the maximum value of the repetition timer, and the maximum propagation delay of a packet in the network. A suggested value is 30 seconds ๐ธ
The copy of the responses MAY be destroyed either T-HIST seconds after the response is issued, or when the gateway (or the Call Agent) receives a confirmation that the response was received, through the "Response Acknowledgement." For transactions acknowledged through this attribute, the gateway SHALL keep a copy of the transaction-id (not the entire transaction response) for T-HIST seconds after the response is issued. That's how it catches and ignores duplicate copies of the transaction request that the network might produce ๐ฆ
3.5.2 Transaction Identifiers and Three Ways Handshake โจ
Okay bestie, transaction identifiers are integer numbers from 1 to 999,999,999 (both included) ๐ข Call-agents can pick a specific number space for each gateway they manage, or use one shared number space for all the gateways in some arbitrary group ๐๏ธ If a call agent wants to split the load of managing a big gateway across several independent processes, those processes MUST then share the transaction number space ๐ค There are a bunch of ways to do this, like centralized allocation of transaction identifiers, or pre-allocating non-overlapping ranges of identifiers to different processes. The implementations MUST guarantee that unique transaction identifiers are allocated to all transactions that originate from a logical call agent, as defined in Section 4. Gateways can just detect duplicate transactions by looking at the transaction identifier alone ๐
The Response Acknowledgement Attribute can show up in any command ๐ It carries a set of "confirmed transaction-id ranges" for final responses that were received. Provisional responses MUST NOT be confirmed ๐ซ And a given response SHOULD NOT be confirmed in two separate messages ๐ โโ๏ธ
MGCP entities MAY choose to delete the copies of the responses (but not the transaction-id) for transactions whose id is inside the "confirmed transaction-id ranges" from the Response Confirmation messages (command or response) they received ๐๏ธ They SHOULD then silently discard further commands from that entity when the transaction-id falls within those ranges, and the response was issued less than T-HIST seconds ago ๐คซ
Entities MUST exercise due caution when acknowledging responses ๐ง In particular, a response SHOULD only be acknowledged if the response acknowledgement is sent to the same entity that the corresponding command (the command whose response is being acknowledged) was sent to.
Likewise, entities SHOULD NOT blindly accept a response acknowledgement for a given response ๐ โโ๏ธ Still, it's considered safe to accept a response acknowledgement for a given response when that acknowledgement comes from the same entity that sent the command which generated that response ๐ซถ
Heads up, using response acknowledgments inside commands (as opposed to the Response Acknowledgement response that follows a provisional response) is OPTIONAL ๐ The perk is that it reduces overall memory consumption. But to avoid large messages, implementations SHOULD NOT generate large response acknowledgement lists ๐ One strategy is to manage responses on a per-endpoint basis. A command for an endpoint can confirm a response to an older command for that same endpoint. Responses to commands with wildcarded endpoint names can be confirmed selectively, with due consideration to message sizes, or they can simply not be acknowledged (unless the response explicitly required a Response Acknowledgement). Just be careful not to confirm the same response twice, or a response that is more than T-HIST seconds old โ ๏ธ
The "confirmed transaction-id ranges" values SHALL NOT be used if more than T-HIST seconds have passed since the entity issued its last response to the other entity, or when an entity resumes operation ๐ In that situation, commands MUST be accepted and processed, without any test on the transaction-id ๐
Commands that carry the "Response Acknowledgement attribute" may arrive out of order ๐ The union of the "confirmed transaction-id ranges" received in recent messages SHALL be retained ๐ง
3.5.3 Computing Retransmission Timers โฑ๏ธ
It's the requesting entity's job to set suitable timeouts for all outstanding commands, and to retry commands once those timeouts are exceeded ๐ฃ And if repeated commands keep failing to get acknowledged, it's also on the requesting entity to seek redundant services and/or clear existing or pending associations ๐งน
The spec purposely doesn't pin down any value for the retransmission timers, because those values are typically network dependent ๐ The retransmission timers SHOULD normally estimate the timer by measuring the time spent between sending a command and getting back the first response to it. At a minimum, a retransmission strategy involving exponential backoff MUST be implemented ๐ One option is to use the algorithm from TCP/IP, which uses two variables:
- the average acknowledgement delay, AAD, estimated through an exponentially smoothed average of the observed delays,
- the average deviation, ADEV, estimated through an exponentially smoothed average of the absolute value of the difference between the observed delay and the current average.
In TCP, the retransmission timer, RTO, is set to the sum of the average delay plus N times the average deviation, where N is a constant. In MGCP, though, the maximum value of the timer SHOULD be bounded, so that no repeated packet gets received by the gateways after T-HIST seconds ๐ A suggested maximum value for RTO (RTO-MAX) is 4 seconds. Implementers SHOULD consider bounding the minimum value of this timer too [19] ๐ฏ
After any retransmission, the MGCP entity SHOULD do the following ๐
- Double the estimated value of the acknowledgement delay for this transaction, T-DELAY.
- Compute a random value, uniformly distributed between 0.5 T-DELAY and T-DELAY.
- Set the retransmission timer (RTO) to the minimum of:
- the sum of that random value and N times the average deviation,
- RTO-MAX.
This procedure has two big effects ๐ข First, because it includes an exponentially increasing component, it automatically slows down the stream of messages when there's congestion. Second, because it includes a random component, it breaks up potential synchronization between notifications triggered by the same external event. Iconic, honestly ๐
Note that the estimators AAD and ADEV SHOULD NOT be updated for transactions that involve retransmissions ๐ โโ๏ธ Also, the first new transmission after a successful retransmission SHOULD use the RTO from that last retransmission. If this transmission succeeds without any retransmissions, the AAD and ADEV estimators get updated and RTO is determined as usual again ๐ See, e.g., [18] for further details ๐
3.5.4 Maximum Datagram Size, Fragmentation and Reassembly ๐ฆ
MGCP messages sent over UDP rely on IP for fragmentation and reassembly of large datagrams ๐งฉ The maximum theoretical size of an IP datagram is 65535 bytes. With a 20-byte IP header and an 8-byte UDP header, that leaves a maximum theoretical MGCP message size of 65507 bytes when using UDP ๐คฏ
BUT, IP doesn't require a host to receive IP datagrams larger than 576 bytes [21], which would give an unacceptably tiny MGCP message size ๐ฌ So MGCP mandates that implementations MUST support MGCP datagrams up to at least 4000 bytes, which requires the matching IP fragmentation and reassembly to be supported ๐ช Quick note: the 4000 byte limit applies at the MGCP level. Lower layers add overhead, so support for IP datagrams larger than this will be needed too. UDP and IP overhead will be at least 28 bytes, and things like IPSec add even more ๐
Also, the above applies to both Call Agents and endpoints ๐ซ Call Agents can audit endpoints to find out whether they support larger MGCP datagrams than specified above ๐ Endpoints currently don't have a similar capability to figure out whether a Call Agent supports larger MGCP datagram sizes ๐
3.5.5 Piggybacking ๐ฅ
There are times when a Call Agent wants to send several messages to the same gateways at the same time, and vice versa ๐ฌ When several MGCP messages have to go in the same datagram, they MUST be separated by a line of text that contains a single dot, like this:
200 2005 OK
.
DLCX 1244 card23/21@tgw-7.example.net MGCP 1.0
C: A3C47F21456789F0
I: FDE234C8
The piggybacked messages MUST be processed exactly as if they had been received one at a time in several separate datagrams ๐ Each message in the datagram MUST be processed to completion and in order, starting with the first message, and each command MUST be responded to ๐ Errors in one piggybacked message MUST NOT affect any of the other messages in that datagram. Every message is processed on its own, periodt ๐
Piggybacking can be used for two things ๐ฏ
- Guaranteed in-order delivery and processing of messages.
- Fate sharing of message delivery.
When piggybacking is used to guarantee in-order delivery, entities MUST ensure this in-order delivery property is kept on retransmissions of the individual messages ๐ An example is when multiple Notify's are sent using piggybacking (as described in Section 4.4.1) ๐จ
Fate sharing of message delivery means either all the messages get delivered, or none of them do ๐ค When piggybacking is used to guarantee this fate sharing, entities MUST also ensure that this property is kept upon retransmission ๐ซถ For example, when a Call Agent receives a Notify from an endpoint operating in lockstep mode, it may want to send the response and a new NotificationRequest command in a single datagram, so both messages share the same delivery fate ๐ฅนโจ
3.5.6. Provisional Responses ๐ฆ
Okay bestie, some transactions just take forever to finish ๐ญ and that's a problem because long execution times can totally mess with the timer-based retransmission thing we talked about ๐
It can cause an inordinate number of retransmissions (way too many, lowkey chaos) or timer values that get too long to be efficient ๐
Gateways (and Call Agents) that can predict a transaction is going to take a long time SHOULD send a provisional response with response code 100 โจ As a guideline, a transaction that needs external communication to finish, like network resource reservation ๐, SHOULD issue a provisional response. Also, entities SHOULD send a provisional response if they receive a repetition of a transaction that hasn't finished executing yet ๐ซถ
Gateways (or Call Agents) that start building up queues of transactions to be executed may send a provisional response with response code 101 to show that's happening (see Section 4.4.8 for more deets) ๐
Pure transactional semantics would imply that provisional responses SHOULD NOT return any information other than the fact that the transaction is currently executing. But an optimistic approach that lets some information come back cuts down on the delay the system would otherwise have ๐ธ
To reduce the delay in the system, it is RECOMMENDED to include a connection identifier and session description in a 100 provisional response to the CreateConnection command. If a session description would be returned by the ModifyConnection command, the session description SHOULD be included in the provisional response here too. If the transaction completes successfully, the information returned in the provisional response MUST be repeated in the final response. It's considered a protocol error not to repeat this information, or to change any of the previously supplied information in a successful response. If the transaction fails, an error code is returned, and the information returned previously is no longer valid ๐
A currently executing CreateConnection or ModifyConnection transaction MUST be cancelled if a DeleteConnection command for the endpoint is received. In that case, a final response for the cancelled transaction SHOULD still be returned automatically (error code 407, transaction aborted, is RECOMMENDED), and a final response for the cancelled transaction MUST be returned if a retransmission of the cancelled transaction is detected (see also Section 4.4.4). ๐จ
MGCP entities that receive a provisional response SHALL switch to a longer repetition timer (LONGTRAN-TIMER) for that transaction. The purpose of this timer is mainly to detect processing failures. The default value of LONGTRAN-TIMER is 5 seconds, but the provisioning process may change it. Retransmissions MUST still satisfy the timing requirements in Section 3.5.1 and 3.5.3, so LONGTRAN-TIMER MUST be smaller than T-HIST (it should in fact be considerably smaller). Also, entities MUST NOT let a transaction run forever. A transaction that the entity times out SHOULD return error code 406 (transaction time-out) โฐ
Per the definition of T-HIST (Section 3.5.1), the maximum transaction execution time is smaller than T-HIST. In a network with low delay, it can reasonably be approximated as T-HIST minus T-MAX. A final response should be received no more than T-HIST seconds after the command was sent initially. Still, entities SHOULD wait for 2*T-HIST seconds before giving up on receiving a final response. Retransmission of the command MUST still cease after T-MAX seconds, though. If no response is received, the outcome of the transaction is not known. If the entity sending the command was a gateway, it now becomes "disconnected" and SHALL initiate the "disconnected" procedure (see Section 4.4.7) ๐ตโ๐ซ
When the transaction finishes executing, the final response is sent and the now-obsolete provisional response is deleted. To make sure a lost final response is spotted quickly, final responses issued after provisional responses for a transaction SHOULD be acknowledged. (Unfortunately, older RFC 2705 implementations may not do this, which is the only reason it isn't an absolute requirement.) ๐ง
So the endpoint SHOULD include an empty "ResponseAck" parameter in those, and only those, final responses. The presence of the "ResponseAck" parameter in the final response SHOULD trigger a "Response Acknowledgement" response to be sent back to the endpoint. The "Response Acknowledgement" response will then include the transaction-id of the response it acknowledges in the response header. For backwards compatibility, entities can't depend on receiving such a "response acknowledgement". Still, it is strongly RECOMMENDED to support this behavior, because excessive delays when packets are lost, plus excessive retransmissions, may happen otherwise ๐ซ
Receiving a "Response Acknowledgement" response follows the same time-out and retransmission strategies and procedures as responses to commands. That means the sender of the final response will retransmit it if a "Response Acknowledgement" isn't received in time ๐ For backwards compatibility, failing to receive a "response acknowledgement" SHOULD NOT affect the roundtrip time estimates for subsequent commands, and it furthermore MUST NOT lead to the endpoint becoming "disconnected". The "Response Acknowledgment" response is never acknowledged ๐
4. States, Failover and Race Conditions โจ
In order to implement proper call signaling, the Call Agent has to keep track of the state of the endpoint, and the gateway has to make sure events are properly notified to the Call Agent. Special conditions exist when the gateway or the Call Agent restarts. The gateway has to be redirected to a new Call Agent during "failover" procedures, and the Call Agent has to take special action when the gateway goes offline or restarts ๐
4.1 Failover Assumptions and Highlights โจ
Okay bestie, before we get into the failover drama, here are the protocol highlights you need to understand how Call Agent fail-over works ๐ง
- Call Agents are identified by their domain name (and optional port), not their network addresses, and several addresses can be associated with a domain name. ๐ธ
- An endpoint has one and only one Call Agent associated with it at any given point in time. The Call Agent associated with an endpoint is the current value of the "notified entity". ๐ The "notified entity" determines where the gateway will send its commands. If the "notified entity" does not include a port number, the default Call Agent port number (
2727) is assumed. NotifiedEntityis a parameter the Call Agent sends to the gateway to set the "notified entity" for the endpoint. ๐- The "notified entity" for an endpoint is the last value of the
NotifiedEntityparameter received for this endpoint. If no explicitNotifiedEntityparameter has ever been received, the "notified entity" defaults to a provisioned value. If no value was provisioned, or an emptyNotifiedEntityparameter was provided (both strongly discouraged), making the "notified entity" empty, the "notified entity" is set to the source address of the last non-audit command for the endpoint. Thus auditing will not change the "notified entity". ๐ฅ - Responses to commands are sent to the source address of the command, regardless of the current "notified entity". When a
Notifymessage needs to be piggybacked with the response, the datagram is still sent to the source address of the new command received, regardless of the current "notified entity". ๐ฆ
The ability for the "notified entity" to resolve to multiple network addresses is so iconic ๐ญ It lets a "notified entity" represent a Call Agent with multiple physical interfaces on it, and/or a logical Call Agent made up of multiple physical systems. The order of network addresses when a DNS name resolves to multiple addresses is non-deterministic, so Call Agent fail-over schemes MUST NOT depend on any order (e.g., a gateway MUST be able to send a "Notify" to any of the resolved network addresses). ๐ Still, the system is likely to be most efficient if the gateway sends commands to the interface it already has a current association with. It is RECOMMENDED that gateways use the following algorithm to achieve that goal ๐
- If the "notified entity" resolves to multiple network addresses, and the source address of the request is one of those addresses, that network address is the preferred destination address for commands.
- If, on the other hand, the source address of the request is not one of the resolved addresses, the gateway must choose one of the resolved addresses for commands.
- If the gateway fails to contact the network address chosen, it MUST try the alternatives in the resolved list as described in Section 4.3. ๐ซถ
If an entire Call Agent becomes unavailable, the endpoints managed by that Call Agent will eventually become "disconnected" ๐ The only ways for these endpoints to become connected again are either for the failed Call Agent to become available, or for a backup call agent to contact the affected endpoints with a new "notified entity". ๐
When a backup Call Agent has taken over control of a group of endpoints, it is assumed that the failed Call Agent will communicate and synchronize with the backup Call Agent in order to transfer control of the affected endpoints back to the original Call Agent. Alternatively, the failed Call Agent could simply become the backup Call Agent. ๐
Heads up, this one is important: handover conflict resolution between separate CAs is not in place. We are relying strictly on the CAs knowing what they are doing and communicating with each other (although AuditEndpoint can be used to learn about the current "notified entity"). If this is not the case, unexpected behavior may occur. ๐ฑ
Note that, as mentioned earlier, the default "notified entity" is provisioned and may include both domain name and port. For small gateways, provisioning may be done on a per endpoint basis. For much larger gateways, a single provisioning element may be provided for multiple endpoints, or even for the entire gateway itself. In either case, once the gateway powers up, each endpoint MUST have its own "notified entity", so provisioned values for an aggregation of endpoints MUST be copied to the "notified entity" for each endpoint in the aggregation before operation proceeds. ๐ Where possible, the RestartInProgress command on restart SHOULD be sent to the provisioned "notified entity" based on an aggregation that allows the "all of" wild-card to be used. This will reduce the number of RestartInProgress messages. โจ
Another way to view the "notified entity" is in terms of associations between gateways and Call Agents. The "notified entity" is a means to set up that association, and it governs where the gateway sends commands. Commands received by the gateway, however, may come from any source. The association is initially provisioned with a provisioned "notified entity", so that on power up, RestartInProgress and persistent events that occur prior to the first NotificationRequest from Call Agents will be sent to the provisioned Call Agent. ๐ง Once a Call Agent makes a request, however, it may include the NotifiedEntity parameter and set up a new association. Since the "notified entity" persists across calls, the association remains intact until a new "notified entity" is provided. ๐ฆ
4.2 Communicating with Gateways ๐
Endpoint names in gateways include a local name indicating the specific endpoint, and a domain name indicating the host/gateway where the endpoint resides. Gateways may have several interfaces for redundancy. ๐
In gateways that have routing capability, the domain name may resolve to a single network address, with internal routing to that address from any of the gateway's interfaces. In others, the domain name may resolve to multiple network addresses, one for each interface. In the latter case, if a Call Agent fails to contact the gateway on one of the addresses, it MUST try the alternates. ๐ธ
4.3 Retransmission, and Detection of Lost Associations โจ
okay so MGCP is organized into transactions ๐
each one is a command plus a response, which is basically the acknowledgement. MGCP rides on UDP, so packets can get lost ๐ญ when there's no timely response, the commands get retransmitted. MGCP entities MUST keep in memory a list of the responses they sent to recent transactions (so every response sent over the last T-HIST seconds) AND a list of the transactions that haven't finished executing yet ๐ง
incoming transaction IDs get compared to the IDs of those recent responses. if there's a match, the entity doesn't run the transaction again, it just repeats the response ๐ if there's no match to a previously answered transaction, the ID gets checked against the list of unfinished transactions. if that matches, the entity doesn't execute it again, but it SHOULD simply send a provisional response. the final response shows up once the command is done running (see Section 3.5.6 for the deets) ๐ฆ
the repetition mechanism is there to guard against four kinds of errors:
- transmission errors, like when a packet gets lost to line noise or a congested queue ๐
- component failure, like when an interface to a Call Agent becomes unavailable ๐
- Call Agent failure, like when a whole Call Agent goes down ๐
- failover, when a new Call Agent is "taking over" transparently ๐
elements should be able to look back at their history and estimate the packet loss rate caused by transmission errors. in a properly configured system that loss rate should be very low, typically less than 1%. if a Call Agent or a gateway has to repeat a message more than a few times, it's very legit to assume something other than a transmission error is happening ๐ for example, with a loss rate of 1%, the probability that 5 consecutive transmission attempts all fail is 1 in 100 billion. that's an event that should happen less than once every 10 days for a Call Agent processing 1,000 transactions per second. (and fr, the number of retransmissions that counts as excessive should depend on the packet loss rate going on at the time.) we should note that the "suspicion threshold", which we'll call "Max1", is normally lower than the "disconnection threshold", which we'll call "Max2". Max2 MUST be set to a larger value than Max1 ๐
here's the MGCP retransmission algorithm in the figure below, and then the explanation after it ๐
Command issued: N=0, T=0
|
| +------------ retransmission: N++ <--------------+
| | |
| | if T <= T-Max then |
| | transmission |
| | +-- to new address, <-+<----------------------|--+
| | | N=0 | | |
V V V | | |
+-----------+ | | |
+-->| awaiting |- new Call Agent ->+ +------------+ | |
| | response |--- timer elapsed --->| T > T-Max ?| | |
| +-----------+ +------------+ ^ ^
| | | | | |
| v +-----(yes)-----+ (no) | |
| (response | | | |
| received) | +------------+ | |
| | | | N >= Max1 ?|-(no)>+ |
| v | +------------+ ^ ^
| +--------+ | | | |
+<(no)-| final ?| | (yes) | |
^ +--------+ | | | |
| | | (if first address & N=Max1, | |
| v | or last address & N=Max2 | |
| (yes) | check DNS) | |
| | | | | |
| v V +---------------+ | |
| (end) | |more addresses?|(yes)-|->+
| | +---------------+ |
| | | ^
| | (no) |
| | | |
| | +------------+ |
| | | N >= Max2 ?|(no)--+
| | +------------+
| | |
| | (yes)
| | |
| | +----------------+
| +----------->| T >= 2*T-HIST ?|
| +----------------+
| | |
| (no) (yes)
+---------------<-----------------------+ |
v
(disconnected)
a classic retransmission algorithm would just count the successive repeats and decide the association is broken after resending the packet an excessive number of times (usually somewhere between 7 and 11 times). but to cover a possible undetected or in-progress "failover", MGCP tweaks the classic approach like this ๐งฉ
- We require that the gateway always checks for the presence of a new Call Agent. It can be noticed either by:
- receiving a command where the
NotifiedEntitypoints to the new Call Agent, or - receiving a redirection response pointing to a new Call Agent.
- receiving a command where the
if a new Call Agent is detected, the gateway MUST start retransmitting outstanding commands for the endpoint(s) redirected to that new Call Agent ๐ responses to new or old commands are still sent to the source address of the command.
- Prior to any retransmission, it is checked that the time elapsed since the sending of the initial datagram is no greater than
T-MAX. if more thanT-MAXtime has elapsed, then retransmissions MUST cease. if more than 2*T-HISThas elapsed, then the endpoint becomes disconnected โณ - if the number of repetitions for this Call Agent is equal to "
Max1", and its domain name wasn't resolved recently (say, within the last 5 seconds or otherwise provisioned), and it isn't already being resolved, then the gateway MAY actively query the domain name server to detect a possible change of the Call Agent interfaces ๐ note that the first repetition is the second transmission. - the gateway may have learned several IP addresses for the Call Agent. if the number of repetitions for this IP address is greater than or equal to "
Max1" and lower than "Max2", and there are more addresses that haven't been tried, then the gateway MUST direct the retransmissions to alternate addresses. also, receiving explicit network notifications like ICMP network, host, protocol, or port unreachable SHOULD lead the gateway to try alternate addresses (with due consideration to possible security issues) ๐ก๏ธ - if there are no more interfaces to try, and the number of repetitions for this address is
Max2, then the gateway SHOULD contact the DNS one more time to see if any other interfaces have become available. the exception is if the domain name was resolved recently (say, within the last 5 seconds or otherwise provisioned), or it's already being resolved. if there still are no more interfaces to try, the gateway is disconnected and MUST initiate the "disconnected" procedure (see Section 4.4.7) ๐
in order to automatically adapt to network load, MGCP specifies exponentially increasing timers. if the initial timer is set to 200 milliseconds, losing a fifth retransmission gets detected after about 6 seconds. that's probably an acceptable waiting delay to detect a failover. the repetitions should keep going after that delay, not only to maybe get past a transient connectivity problem, but also to give some more time for a failover to finish. waiting a total of 30 seconds is probably acceptable โฐ
it's really important that the maximum delay of retransmissions is bounded ๐ง prior to any retransmission, it's checked that the time (T) elapsed since the sending of the initial datagram is no greater than T-MAX. if more than T-MAX time has elapsed, retransmissions MUST cease. if more than 2*T-HIST time has elapsed, the endpoint becomes disconnected. T-MAX is related to T-HIST: the T-HIST value MUST be greater than or equal to T-MAX plus the maximum propagation delay in the network ๐งฎ
the default value for T-MAX is 20 seconds. so if the assumed maximum propagation delay is 10 seconds, responses to old transactions have to be kept for at least 30 seconds. honestly, the sender and receiver agreeing on these values can't be overstated ๐ซถ
the default value for Max1 is 5 retransmissions and the default value for Max2 is 7 retransmissions. both of these can be altered by the provisioning process โ๏ธ
the provisioning process MUST be able to disable one or both of the Max1 and Max2 DNS queries ๐
โโ๏ธ
4.4 Race Conditions ๐
MGCP handles race conditions with a "quarantine list" and with explicit detection of desynchronization, like mismatched hook state caused by glare on an endpoint ๐ฏ
MGCP does not assume the transport mechanism keeps commands and responses in order. this can cause race conditions, which a proper Call Agent can help avoid. (ngl, some race conditions are inherent to distributed systems and would still happen even if the commands were sent in strict order ๐คทโโ๏ธ)
sometimes lots of gateways decide to restart at the same time ๐ฑ this could happen if an area loses power or transmission during an earthquake or an ice storm. once power and transmission come back, many gateways might send "RestartInProgress" commands all at once, and that makes operation super unstable ๐ช๏ธ
4.4.1 Quarantine List ๐ง
MGCP controlled gateways get "notification requests" asking them to watch for a list of "events". the stuff that decides how those events get handled is the "Requested Events" list, the "Digit Map", the "Quarantine Handling", and the "Detect Events" list ๐ธ
Okay bestie, so when the endpoint first wakes up ๐, its requested events list only has the persistent events in it, and the digit map is just assumed to be empty ๐. At this point the endpoint MAY use an implicit NotificationRequest with the reserved RequestIdentifier zero ("0") to detect and report a persistent event, like off-hook ๐. And a pre-existing off-hook condition MUST here result in the off-hook event being generated too ๐ญ no skipping that!
The endpoint then waits for a NotificationRequest command โณ. Once that shows up, the gateway starts watching the endpoint for the events in the list, persistent ones included โจ.
The events get checked as they happen ๐. What happens next depends on the "action" parameter attached to the event in the requested events list, plus the digit map ๐บ๏ธ. Events marked "accumulate" or "accumulate according to digit map" get stacked up in a list of events ๐. The ones marked "accumulate according to digit map" also get stacked into the "current dial string" ๐ฑ. This keeps going until one event shows up that triggers a notification, which gets sent to the "current notified entity" ๐จ.
Now the gateway sends the Notify command and puts the endpoint into a "notification" state ๐. While the endpoint is in that state, any events that are supposed to be detected get tucked into a "quarantine" buffer (FIFO) so they can be processed later ๐งบ. They're basically on hold, quarantined ๐. All events in the union of the RequestedEvents parameter and the most recently received DetectEvents parameter SHALL be detected and quarantined, no matter what action is attached to them ๐ . If there's no DetectEvents parameter, then every event mentioned in RequestedEvents does the same thing. Persistent events count as implicitly included in RequestedEvents too ๐ง. If the quarantine buffer hits the endpoint's capacity, a Quarantine Buffer Overflow event (see Appendix B) SHOULD be generated ๐จ. And if the endpoint supports that event, it MUST make sure it has room to include it in the quarantine buffer ๐ซถ. Any extra events after that just get thrown out ๐๏ธ.
The endpoint leaves the "notification state" once it gets a response to the Notify command, whether that response is a success or a failure ๐. The Notify command can be retransmitted while the endpoint is in that state, as described in Section 3.5 and 4 ๐. Now, if the endpoint is or becomes disconnected (see Section 4.3) during all this, a response to the Notify will never arrive ๐. So that Notify is lost and no longer pending, but the endpoint is still stuck in the "notification state" ๐ต. When that happens, finishing the disconnected procedure in Section 4.4.7 SHALL then lead the endpoint out of the "notification state" ๐.
When the endpoint leaves the "notification state", it resets its list of observed events and its "current dial string" to a null value ๐งน.
After that point, what the gateway does depends on the QuarantineHandling parameter in the NotificationRequest command that triggered all this ๐ง:
If the Call Agent said it expected at most one notification in response to the notification request command, then the gateway SHALL simply keep accumulating events in the quarantine buffer until the next notification request command shows up ๐ฆ.
But if the gateway is allowed to send multiple successive Notify commands, here's what it does ๐. When it leaves the "notification state", it resets the list of observed events and the "current dial string" to null, and then starts processing the quarantined events using the list of requested events and digit map it already got ๐. While it's processing these, it might run into an event that triggers a Notify command. If that happens, the gateway can pick one of two behaviors ๐:
- it can immediately transmit a Notify command that reports all the events accumulated in the list of observed events up to and including the triggering event, leaving the unprocessed events in the quarantine buffer,
- or it can try to empty the quarantine buffer and send a single Notify command reporting several sets of events (in one list of observed events) and possibly several dial strings. The "current dial string" gets reset to null after each triggering event. The events after the last triggering event stay in the quarantine buffer.
If the gateway sends a Notify command, the endpoint goes back into and stays in the "notification state" until the acknowledgement comes in (same as described above) ๐. If the gateway doesn't find a quarantined event that triggers a Notify command, it puts the endpoint into a normal state ๐ธ. Events are then handled as they come, exactly as if a Notification Request command had just been received ๐.
A gateway can get a new Notification Request command for the endpoint at any time ๐ฌ, including when the endpoint is disconnected. Activating an embedded Notification Request counts as receiving a new Notification Request too, except the current list of ObservedEvents stays as is instead of being processed again ๐ง . If a new notification request comes in while the endpoint is in the notification state, the gateway SHALL make sure the pending Notify gets to the Call Agent before any new Notify does (and yes, a Notify that got lost because of a disconnect doesn't count as pending anymore ๐). It does this by using the "piggybacking" feature of the protocol ๐. The messages then get sent together in one packet to the current "notified entity" ๐ฆ. Here are the steps ๐:
- a) the gateway sends a response to the new notification request.
- b) the endpoint is then taken out of the "notification state" without waiting for the acknowledgement of the pending Notify command.
- c) a copy of the unacknowledged Notify command is kept until an acknowledgement comes in. If a timer goes off, the Notify gets retransmitted โฐ.
- d) If the gateway has to send a new Notify before the previous Notify(s) get acknowledged, it builds a packet that piggybacks a repeat of the old Notify(s) and the new Notify (ordered by age, oldest first) ๐ฅ. That datagram goes to the current "notified entity".
- f) Gateways that can't piggyback several messages in the same datagram, and so can't guarantee in-order delivery of two (or more) Notify's, SHALL leave the endpoint in the "notification" state for as long as the last Notify isn't acknowledged ๐.
Here's the whole procedure as a diagram ๐บ๏ธ:
+-------------------+
| Processing Events |<--------------------------------------+
+-------------------+ |
| |
Need to send NTFY |
| |
v |
+-------------------+ |
| Outstanding NTFY |---- No -------+ |
| | | |
+-------------------+ v |
| +-----------+ |
Yes | Send NTFY | |
| +-----------+ |
v | |
+--------------------+ v |
| Piggyback new NTFY | +--------------------+ |
| w. old outstanding |---->| Notification State | |
| NTFY(s) | +--------------------+ |
+--------------------+ | | |
new RQNT NTFY response |
received received |
| | |
| v |
| +-------------+ |
| | Step mode ? |- No ->+
| +-------------+ ^
| | |
| Yes |
| | |
| v |
| +---------------+ |
| | Wait for RQNT | |
| +---------------+ |
| | |
| RQNT received |
| | |
| v |
| +---------------+ |
+------>| Apply RQNT and|----->+
| send response |
+---------------+
Gateways can also try to deliver the pending Notify before they get a successful response to the new NotificationRequest, by using the "piggybacking" feature ๐. Back in RFC 2705 this was actually required behavior, but doing it has a bunch of complications ๐ , and the benefits are questionable ๐คทโโ๏ธ. The big issue is that the RFC 2705 mechanism didn't guarantee in-order delivery of Notify's and responses to NotificationRequests in general, so Call Agents had to handle out-of-order delivery of these messages anyway ๐. Making this optional is backwards compatible and way less complex, so it's a win-win ๐.
After the gateway gets the Notification Request command, the requested events list and digit map (if a new one was provided) get replaced by the newly received parameters, and the current dial string gets reset to null ๐. Also, if the Notification Request came in while the endpoint was in the "notification state", the list of observed events gets reset to null too ๐งผ. What happens next depends on the QuarantineHandling parameter ๐ง. It can say the quarantined events (and observed events, which in this case is now an empty list) should be discarded, and if so, they will be ๐๏ธ. Or it can say the quarantined (and observed) events should be processed. In that case the gateway starts processing them using the newly received list of requested events and digit map (if provided) ๐. If it runs into an event that requires a Notify command, the gateway immediately sends a Notify command reporting all events accumulated in the list of observed events up to and including the triggering event, leaves the unprocessed events in the quarantine buffer, and enters the "notification state" ๐โจ.
A brand-new NotificationRequest can show up while the gateway is still holding events from the previous one ๐. The gateway hasn't spotted a notification-triggering event yet, so the endpoint isn't in the "notification state" ๐ซ . So what happens to those not-yet-notified events? It's the same deal as the quarantined ones, and it all comes down to the quarantine handling parameter ๐
- If the quarantine-handling parameter says quarantined events shall be ignored, the observed events list just gets reset ๐งน
- If the quarantine-handling parameter says quarantined events shall be processed, the observed event list gets moved into the quarantined event list ๐ฆ. Then the observed event list is reset, and the quarantined event list gets processed ๐
Call Agents controlling endpoints in lockstep mode SHOULD send the response to a successful Notify and the new NotificationRequest together in one datagram, using piggybacking ๐งโจ
4.4.2 Explicit Detection
Okay, the hook position is like, THE key piece of state for a bunch of endpoints ๐. A race condition can happen when the user goes off-hook before the Call Agent has time to ask the gateway to notify an off-hook event (the "glare" condition everyone in telephony knows ๐). It can also happen when the user goes on-hook before the Call Agent gets to request that event's notification ๐ญ.
To dodge this race, the gateway MUST check the endpoint's condition before it acknowledges a NotificationRequest. It MUST return an error:
- If the gateway is asked to notify an "off-hook" transition while the phone is already off-hook (error code 401 - phone off hook) ๐ต
- If the gateway is asked to notify an "on-hook" or "flash hook" condition while the phone is already on-hook (error code 402 - phone on hook) ๐ โโ๏ธ
Individual signal definitions can also say a signal only works under certain conditions. For example, ringing may only be possible if the phone is already off-hook ๐. If a signal has prerequisites like that, the gateway MUST return the error specified in the signal definition whenever the prerequisite isn't met ๐ซ.
Here's the tea โ: the condition check happens at the moment the notification request is received. The actual event that caused the current condition might have been reported earlier, ignored earlier, or might currently be quarantined ๐ฐ๏ธ.
The other state variables, like the list of RequestedEvents or the list of requested signals, get entirely replaced after each successful NotificationRequest ๐. That's what stops any long-term discrepancy between the Call Agent and the gateway ๐ซถ.
When a NotificationRequest is unsuccessful, whether or not it's included in a connection-handling command, the gateway MUST simply continue as if the command had never been received ๐ซฅ. Like all other transactions, the NotificationRequest MUST operate as an atomic transaction, so any changes initiated as a result of the command MUST be reverted ๐.
Another race condition can happen when a Notify is issued shortly before the gateway receives a NotificationRequest ๐โโ๏ธ. The RequestIdentifier is what correlates Notify commands with NotificationRequest commands. That lets the Call Agent figure out whether the Notify was generated before or after the gateway got the new request ๐ต๏ธโโ๏ธ. This is especially important for avoiding deadlocks in "step" mode ๐จ.
4.4.3 Transactional Semantics
As the potential transaction completion times grow, e.g., because of external resource reservations, defining the transactional semantics carefully becomes more and more important ๐ง. Race conditions, like the ones involving hook-state, really need careful definitions too ๐ฏ.
Here's a big point: a pre-condition (like hook-state) might change between the moment a transaction starts and the moment it either completes successfully (transaction commit) or fails ๐ข. In general, a transaction's success depends on one or more pre-conditions, and any of them can change dynamically between transaction start and transaction commit ๐ซ.
The simplest approach is to require that all pre-conditions be met from the moment the transaction is initiated until it commits. If any pre-condition isn't met before the transaction completes, the transaction fails too ๐ฅ.
Take a transaction that includes a request for the "off-hook" event. When it's initiated, the phone is "on-hook", so that pre-condition is met โ . If the hook-state changes to "off-hook" before the transaction completes, the pre-condition no longer holds, and the transaction immediately fails ๐ต.
Now for timing. When does a new transaction take effect, and when does processing according to an old one stop? ๐ค Say transaction T1 executed successfully, and event processing is currently being done according to T1. Then we receive a new transaction T2 that specifies new event processing (for example, a CreateConnection with an encapsulated NotificationRequest). We don't know whether T2 will complete successfully, so we can't start processing events according to T2 until its outcome is known ๐. We could suspend all event processing until then, but that would make the system less responsive, so that SHOULD NOT be done ๐
โโ๏ธ.
Instead, when a new transaction Ty is received and Ty modifies processing according to an old transaction Tx, processing according to Tx SHOULD remain active for as long as possible, until a successful outcome of Ty is known to occur โจ. If Ty fails, processing according to Tx just continues as usual ๐ซก. Any changes incurred by Ty logically take effect when Ty commits ๐.
So if the endpoint was in the notification state when Ty commits, and Ty contained a NotificationRequest, the endpoint gets taken out of the notification state when Ty commits ๐. This holds whether or not the endpoint was in the notification state when Ty was initiated ๐. For example, a Notify could be generated due to processing according to Tx between the start and commit of Ty ๐จ. If the commit of Ty leads to the endpoint entering the notification state, a new NotificationRequest (Tz) is needed to exit it ๐. That follows from the fact that transaction execution respects causal order ๐ง .
One more thing! Wildcards, especially the "all of" wildcard, can match more than one endpoint ๐. When a command is requested and the endpoint identifier matches more than one endpoint, transactional semantics still apply ๐. So the command MUST either succeed for all the endpoints, or it MUST fail for all of them ๐ซถ. A single response is always issued ๐.
4.4.4 Ordering of Commands, and Treatment of Misorder โจ
okay so MGCP does NOT require the transport to guarantee in-order delivery of commands to a gateway or an endpoint ๐. This keeps actions snappy and timely, but it has a few drawbacks, ngl ๐:
- Notify commands can get delayed and show up at the Call Agent after a new Notification Request command has already been sent ๐ญ,
- If a new NotificationRequest goes out before the previous one is acknowledged, there's no guarantee the old one won't get received and executed after the new one ๐.
Call Agents that want their endpoints to behave consistently can follow these rules ๐:
- When a gateway handles several endpoints, commands for different endpoints can be sent in parallel, like a model where each endpoint has its own process or its own thread ๐ง.
- When several connections are created on the same endpoint, commands for different connections can be sent in parallel.
- On a given connection, there should normally be only one outstanding command (create or modify). BUT a DeleteConnection command can be issued at any time ๐ค, so a gateway might sometimes get a ModifyConnection for a connection that was already deleted. Those will fail, and an error code MUST be returned (error code 515 - incorrect connection-id, is RECOMMENDED) ๐ .
- On a given endpoint, there should normally be only one outstanding NotificationRequest command at any time. The RequestId parameter MUST be used to correlate Notify commands with the notification request that triggered them ๐.
- An implicitly or explicitly wildcarded DeleteConnection command that applies to a group of endpoints can cut in front of a pending CreateConnection command ๐. The Call Agent should individually delete all connections whose completion was pending when the global DeleteConnection was sent. Also, new CreateConnection commands for endpoints named by the wild-carding SHOULD NOT be sent until the wild-carded DeleteConnection command is acknowledged ๐.
- When commands are embedded within each other, sequencing requirements for all commands must be adhered to. For example, a Create Connection command with a Notification Request in it must follow the sequencing requirements for both CreateConnection and NotificationRequest at the same time ๐งฉ.
- AuditEndpoint and AuditConnection are not subject to any sequencing requirements ๐ซถ.
- RestartInProgress MUST always be the first command an endpoint sends, as defined by the restart procedure ๐. Any other command or non-restart response (see Section 4.4.6), except for responses to auditing, MUST be delivered after this RestartInProgress command (piggybacking allowed) ๐ธ.
- When multiple messages are piggybacked in a single packet, the messages are always processed in order ๐ฆ.
- On a given endpoint, there should normally be only one outstanding EndpointConfiguration command at any time ๐.
Gateways MUST NOT make any assumptions about whether Call Agents follow these rules or not ๐ . So gateways MUST always respond to commands, regardless of whether they follow the rules above. To keep things consistent, gateways SHOULD behave as described below when one or more of the rules above aren't followed ๐ฆ:
- Where a single outstanding command is expected (ModifyConnection, NotificationRequest, and EndpointConfiguration), but the same command arrives in a new transaction before the old one finishes executing, the gateway SHOULD fail the previous command. This includes the case where one or more of the commands were encapsulated. The use of error code 407 (transaction aborted) is RECOMMENDED ๐.
- If a ModifyConnection command is received for a pending CreateConnection command, the ModifyConnection command SHOULD simply be rejected. The use of error code 400 (transient error) is RECOMMENDED. Note that this situation counts as a Call Agent programming error ๐ฌ.
- If a DeleteConnection command is received for a pending CreateConnection or ModifyConnection command, the pending command MUST be aborted. The use of error code 407 (transaction aborted) is RECOMMENDED ๐.
Note, that where reception of a new command leads to aborting an old command, the old command SHOULD be aborted regardless of whether the new command succeeds or not. For example, if a ModifyConnection command is aborted by a DeleteConnection command which itself fails due to an encapsulated NotificationRequest, the ModifyConnection command is still aborted ๐ฅ.
4.4.5 Endpoint Service States ๐
As we covered earlier, endpoints configured for operation can be either in-service or out-of-service ๐. An endpoint's actual service-state is shown by the combo of its RestartMethod and RestartDelay parameters. Those get sent with RestartInProgress commands (Section 2.3.12), and they can also be audited in AuditEndpoint commands (Section 2.3.10) ๐.
The service-state changes how an endpoint handles a command ๐. An in-service endpoint MUST process any command it receives. An out-of-service endpoint MUST reject non-auditing commands, but SHOULD process auditing commands if it can. For backwards compatibility, auditing commands for an out-of-service endpoint may also be rejected instead. Any command rejected because the endpoint is out-of-service SHOULD generate error code 501 (endpoint not ready/out-of-service) ๐ซ.
Note that (per Section 2.1.2), unless specified otherwise for a command, endpoint names with the "any of" wildcard only refer to in-service endpoints ๐, while names with the "all of" wildcard refer to all endpoints, regardless of service state โจ.
The table below shows the current service-states and how the gateway processes commands, depending on the RestartInProgress command sent and the response (if any) received to it. The last column also lists, in parentheses, the RestartMethod that gets returned if audited ๐:
------------------------------------------------------------------
| Restart- | Restart- | 2xx | Service- | Response to |
| Method | Delay | received ?| State | new command |
|------------------------------------------------------------------|
| graceful | zero | Yes/No | In | non-audit: 2xx |
| | | | | audit: 2xx |
| | | | | (graceful) |
|-----------+----------+-----------+----------+--------------------|
| graceful | non-zero | Yes/No | In* | non-audit: 2xx |
| | | | | audit: 2xx |
| | | | | (graceful) |
|-----------+----------+-----------+----------+--------------------|
| forced | N/A | Yes/No | Out | non-audit: 501 |
| | | | | audit: 2xx |
| | | | | (forced) |
|-----------+----------+-----------+----------+--------------------|
| restart | zero | No | In | non-audit: 2xx,405*|
| | | | | audit: 2xx |
| | | | | (restart) |
|-----------+----------+-----------+----------+--------------------|
| restart | zero | Yes | In | non-audit: 2xx |
| | | | | audit: 2xx |
| | | | | (restart) |
|-----------+----------+-----------+----------+--------------------|
| restart | non-zero | No | Out* | non-audit: 501* |
| | | | | audit: 2xx |
| | | | | (restart) |
|-----------+----------+-----------+----------+--------------------|
| restart | non-zero | Yes | Out* | non-audit: 501* |
| | | | | audit: 2xx |
| | | | | (restart) |
|-----------+----------+-----------+----------+--------------------|
| discon- | zero/ | No | In | non-audit: 2xx, |
| nected | non-zero | | | audit: 2xx |
| | | | | (disconnected)|
|-----------+----------+-----------+----------+--------------------|
| discon- | zero/ | Yes | In | non-audit: 2xx |
| nected | non-zero | | | audit: 2xx |
| | | | | (restart) |
|-----------+----------+-----------+----------+--------------------|
| cancel- | N/A | Yes/No | In | non-audit: 2xx |
| graceful | | | | audit: 2xx |
| | | | | (restart) |
------------------------------------------------------------------
Notes (*):
- The three service-states marked with "*" will change after the expiration of the RestartDelay ๐ฐ๏ธ, and at that point an updated RestartInProgress command SHOULD be sent โฐ.
- If the endpoint returns 2xx when the restart procedure has not yet completed, then in-order delivery MUST still be satisfied, i.e., piggy-backing is to be used ๐ฆ. If the command is not processed instead, 405 SHOULD be returned ๐ .
- Following a "restart" RestartInProgress with a non-zero RestartDelay, error code 501 is only returned until the endpoint goes in-service, i.e., until the expiration of the RestartDelay ๐ท.
4.4.6 Fighting the Restart Avalanche โจ
Okay so picture this, bestie ๐ญ: a bunch of gateways get powered on at the same time. If they all fired off a RestartInProgress transaction together, the Call Agent would literally get swamped ๐, and you'd get lost messages and network congestion right when service is trying to come back. Not it ๐ โโ๏ธ. So to stop these avalanches, the following behavior is REQUIRED ๐ซถ:
- When a gateway is powered on, it MUST start a restart timer set to a random value, uniformly distributed between 0 and a maximum waiting delay (MWD). Care should be taken to avoid synchronicity of the random number generation between multiple gateways that would use the same algorithm ๐ฒ.
- The gateway MUST then wait for whichever of these happens first: the end of this timer, the reception of a command from the Call Agent, or the detection of a local user activity, such as an off-hook transition on a residential gateway ๐.
- When the timer elapses, when a command is received, or when an activity is detected, the gateway MUST initiate the restart procedure ๐.
The restart procedure basically means the endpoint has to guarantee that the first
- non-audit command, or
- non-restart response (i.e., error codes other than
405,501, and520) to a non-audit command
that the Call Agent sees from this endpoint is a "restart" RestartInProgress command. The endpoint is totally free to use piggybacking to make this happen ๐. Endpoints that are considered in-service will have a RestartMethod of "restart", while endpoints considered out-of-service will have a RestartMethod of "forced" (also see Section 4.4.5) ๐ธ. Commands rejected because an endpoint hasn't finished the restart procedure yet SHOULD use error code 405 (endpoint "restarting") ๐
.
The restart procedure is complete once a success response has been received. If an error response shows up, what happens next depends on the error code:
- If the error code indicates a transient error (4xx), then the restart procedure MUST be initiated again (as a new transaction) ๐.
- If the error code is
521, then the endpoint is redirected, and the restart procedure MUST be initiated again (as a new transaction). The521response MUST have included a NotifiedEntity, which is the "notified entity" the restart gets sent towards. If it didn't include a NotifiedEntity, the response is treated as any other permanent error (see below) ๐. - If the error is any other permanent error (5xx), and the endpoint is not able to fix it, then the endpoint stops starting the restart procedure on its own (until it's rebooted/restarted) unless otherwise specified. If a command is received for the endpoint, the endpoint MUST initiate the restart procedure again ๐ฅบ.
Note that if the RestartInProgress is piggybacked with the response (R) to a command received while restarting, then retransmitting the RestartInProgress doesn't require piggybacking the response R again. However, while the endpoint is restarting, resending the response R DOES require the RestartInProgress to be piggybacked, so the two arrive in order ๐ฆ.
If the gateway enters the "disconnected" state while it's in the middle of the restart procedure, the disconnected procedure specified in Section 4.4.7 MUST be carried out. The only difference is that a "restart" message is sent instead of a "disconnected" one ๐จ.
Each endpoint in a gateway has a provisionable Call Agent, aka the "notified entity," to send the initial restart message to ๐จ. When a gateway's endpoints are managed by more than one Call Agent, the above procedure MUST be performed for each collection of endpoints managed by a given Call Agent. The gateway MUST take full advantage of wild-carding to keep the number of RestartInProgress messages down when multiple endpoints restart and are managed by the same Call Agent ๐. Heads up: during startup, endpoints can begin out-of-service and then become in-service as part of gateway initialization ๐. So a gateway may send a "forced" RestartInProgress for all its endpoints first, and then a "restart" RestartInProgress for the ones that come in-service. Or it can just send "restart" for the in-service endpoints and "forced" for the specific endpoints that are out-of-service. Either way, wild-carding MUST still be used to minimize the number of messages sent โจ.
The value of MWD is a configuration parameter that depends on the type of gateway. Here's the reasoning for working out that delay on residential gateways ๐ .
Call agents are usually dimensioned to handle the peak hour traffic load, when on average 10% of the lines are busy, placing calls that last about 3 minutes. Processing a call usually involves 5 to 6 MGCP transactions between each endpoint and the Call Agent. Doing the math, the Call Agent handles 5 to 6 transactions per endpoint every 30 minutes on average, or, put another way, about one transaction per endpoint every 5 to 6 minutes on average ๐งฎ. This suggests that a reasonable value of MWD for a residential gateway would be 10 to 12 minutes. Without explicit configuration, residential gateways should adopt a value of 600 seconds for MWD โฐ.
The same reasoning says MWD should be much shorter for trunking gateways or business gateways ๐ข. They handle a ton of endpoints, and those endpoints are used way more than 10% of the time during the peak busy hour, with a typical value being 60%. During the peak hour, these endpoints are expected to add about one transaction per minute to the Call Agent load ๐. A reasonable algorithm is to make the MWD per "trunk" endpoint six times shorter than the MWD per residential gateway, and also inversely proportional to the number of endpoints being restarted ๐ง . For example, MWD should be set to 2.5 seconds for a gateway handling a T1 line, or to 60 milliseconds for a gateway handling a T3 line ๐ฆ.
4.4.7 Disconnected Endpoints ๐
okay so besides the restart procedure, gateways also get a "disconnected" procedure ๐ซถ and it MUST be initiated when an endpoint becomes "disconnected" as described in Section 4.3. ngl it should be noted that endpoints can only become disconnected when they try to talk to the Call Agent ๐ The following steps MUST be followed by an endpoint that becomes "disconnected":
- okay so the "disconnected" timer gets set to a random value, uniformly distributed between 1 and a provisionable "disconnected" initial waiting delay (Tdinit), e.g., 15 seconds. Care MUST be taken to avoid synchronicity of the random number generation between multiple gateways and endpoints that would use the same algorithm ๐
- then the gateway just waits for whichever happens first: the timer ends, a command for the endpoint shows up from the Call Agent, or it detects some local user activity for the endpoint, like an off-hook transition for example ๐
- when the "disconnected" timer runs out, when a command gets received for the endpoint, or when local user activity gets detected for the endpoint, the gateway starts the "disconnected" procedure for the endpoint. if a disconnected procedure was already going, it just gets replaced by the new one ๐ Also, for local user activity, a provisionable "disconnected" minimum waiting delay (Tdmin) MUST have elapsed since the endpoint became disconnected or the last time it ended the "disconnected" procedure. This keeps the rate of the procedure in check ๐ If Tdmin hasn't passed yet, the endpoint simply goes back to step 2, without messing with any disconnected procedure already in progress.
- if the "disconnected" procedure still left the endpoint disconnected, the "disconnected" timer gets doubled, capped by a provisionable "disconnected" maximum waiting delay (Tdmax), e.g., 600 seconds. then the gateway goes back to step 2 (using a new transaction-id) ๐ธ
The "disconnected" procedure is kind of a copy of the restart procedure, because it also says the endpoint MUST send a RestartInProgress command to the Call Agent to tell it the endpoint was disconnected ๐ฃ The endpoint MUST also guarantee that the first non-audit message (non-audit command or response to non-audit command) the Call Agent sees from it MUST inform the Call Agent that the endpoint is disconnected (unless the endpoint goes out-of-service). When a command (C) comes in, this happens by sending a piggy-backed datagram with a "disconnected" RestartInProgress command and the response to command C, sent to the source address of command C instead of the current "notified entity" โจ This piggy-backed RestartInProgress doesn't get automatically retransmitted by the endpoint. It just relies on fate-sharing with the piggy-backed response to keep the in-order delivery requirement safe ๐ฆ The Call Agent still sends a response to the piggy-backed RestartInProgress, as usual, but that response may get lost. On top of the piggy-backed RestartInProgress command, a new "disconnected" procedure gets triggered by the command that came in. This leads to a non piggy-backed copy (i.e., same transaction) of the "disconnected" RestartInProgress command being sent reliably to the current "notified entity" ๐
When the Call Agent finds out the endpoint is disconnected, it may then decide to audit the endpoint, or just clear all connections for the endpoint ๐งน Each such "disconnected" procedure gives you a new RestartInProgress command, and that one is subject to the normal retransmission procedures in Section 4.3. So at the end of the procedure, the endpoint may still be "disconnected" ๐ญ If the endpoint goes out-of-service while it's disconnected, it SHOULD send a "forced" RestartInProgress message as described in Section 2.3.12.
The disconnected procedure is complete once a success response has been received. Error responses get handled kind of like the restart procedure (Section 4.4.6) ๐ If the "disconnected" procedure has to start again after an error response, the rate-limiting timer considerations from above still apply.
Heads up, if the RestartInProgress is piggybacked with the response (R) to a command received while the endpoint is disconnected, then retransmitting that particular RestartInProgress doesn't need the response R piggybacked too ๐ BUT while the endpoint is disconnected, resending the response R does need the RestartInProgress piggybacked with it, so the two stay in order ๐ฅ
If a bunch of disconnected endpoints share the same "notified entity", and the set can be named with a wildcard, the gateway MAY swap the individual disconnected procedures for one suitably wildcarded disconnected procedure instead ๐ In that case, the Restart Delay for the wildcarded "disconnected" RestartInProgress command SHALL be the Restart Delay of the oldest disconnected procedure that got replaced. Be careful though: if only some of these endpoints later get their "notified entity" changed and/or stop being disconnected, that wildcarded disconnected procedure can't be used anymore. The remaining individual disconnected procedures MUST then be resumed again ๐
A disconnected endpoint may want to send a command (besides RestartInProgress) while it's disconnected. That will only work once the Call Agent is reachable again, which raises the question of what to do with such a command in the meantime ๐ค At one extreme, the endpoint could drop the command right away. But that wouldn't work very well when the Call Agent was actually available and the endpoint just hadn't finished the "disconnected" procedure yet. Picture this: a NotificationRequest was just received, which immediately resulted in a Notify being generated ๐ฌ To prevent scenarios like that, disconnected endpoints SHALL NOT blindly drop new commands to be sent for a period of T-MAX seconds after they receive a non-audit command ๐
One way to meet this requirement is to temporarily buffer the commands to be sent. But while doing that, the endpoint MUST ensure that it:
- does not build up a long queue of commands to be sent,
- does not swamp the Call Agent by rapidly sending too many commands once it is connected again.
Buffering commands for T-MAX seconds and then, once the endpoint is connected again, limiting the rate at which buffered commands get sent to one outstanding command per endpoint is considered acceptable (see also Section 4.4.8, especially if using wildcards) ๐ฆ If the endpoint isn't connected within T-MAX seconds, but a "disconnected" procedure starts within T-MAX seconds, the endpoint MAY piggyback the buffered command(s) with that RestartInProgress โจ Also, once a command has been sent, whether it was buffered first or piggybacked earlier, retransmission of that command MUST cease T-MAX seconds after the initial send, as described in Section 4.3 โฐ
This specification purposely doesn't define any extra behavior for a disconnected endpoint ๐คทโโ๏ธ Vendors MAY for instance choose to provide silence, play reorder tone, or even enable a downloaded wav file to be played ๐ถ
The default value for Tdinit is 15 seconds, the default value for Tdmin, is 15 seconds, and the default value for Tdmax is 600 seconds ๐ง
4.4.8 Load Control in General ๐
The previous sections covered several MGCP mechanisms for dealing with congestion and overload, namely:
- the UDP retransmission strategy which adapts to network and call agent congestion on a per endpoint basis,
- the guidelines on the ordering of commands which limit the number of commands issued in parallel,
- the restart procedure which prevents flooding in case of a restart avalanche, and
- the disconnected procedure which prevents flooding in case of a large number of disconnected endpoints.
It's still possible for a given set of endpoints, on the same or different gateways, to issue one or more commands at the same moment ๐ณ Sure, you could argue Call Agents should be sized to handle one message per served endpoint at any given point in time, but that's not always the case in practice. Likewise, gateways may not be able to handle a message for all of their endpoints at once. In general, these issues can be handled with a credit-based mechanism, or by monitoring and automatically adapting to the observed behavior. We go with the second option, like so ๐
Conceptually, Call Agents and gateways keep a queue of incoming transactions to be executed. This transaction queue has a high-water mark and a low-water mark attached. Once the queue length hits the high-water mark, the entity SHOULD start issuing 101 provisional responses (transaction queued) until the queue length drops to the low-water mark. This applies to new transactions and to retransmissions too. If the entity can't process any new transactions right now, it SHOULD return error code 409 (processing overload) ๐ฆ
Also, gateways SHOULD adjust the sending rate of new commands to a given Call Agent by monitoring the observed response times from that Call Agent to a set of endpoints. If the observed smoothed average response time suddenly rises significantly over some threshold, or the gateway receives a 101 (transaction queued) or 409 (overload) response, the gateway SHOULD adjust the sending rate of new commands to that Call Agent accordingly. The details of the smoothing average algorithm, the rate adjustments, and the thresholds involved are for further study, but they MUST be configurable ๐ง
Similarly, Call Agents SHOULD adjust the sending rate of new transactions to a given gateway by monitoring the observed response times from that gateway for a set of endpoints. If the observed smoothed average response time suddenly rises significantly over some threshold, or the Call Agent receives a 101 (transaction queued) or 409 (overloaded), the Call Agent SHOULD adjust the sending rate of new commands to that gateway accordingly. The details of the smoothing average algorithm, the rate adjustments, and the thresholds involved are for further study, but they MUST be configurable ๐ธ
5. Security Requirements ๐โจ
okay bestie, security time ๐ซถ anyone can send a command to an MGCP endpoint, which is giving chaos ๐. if unauthorized entities could use MGCP, they could set up calls they shouldn't, or mess with calls that are already happening. so the expectation is that MGCP messages will always travel over secure Internet connections, as defined in the IP security architecture from RFC 2401, using either the IP Authentication Header from RFC 2402 or the IP Encapsulating Security Payload from RFC 2406. the complete MGCP protocol stack ends up looking like this:
-------------------------------
| MGCP |
|-------------------------------|
| UDP |
|-------------------------------|
| IP security |
| (authentication or encryption)|
|-------------------------------|
| IP |
|-------------------------------|
| transmission media |
-------------------------------
Adequate protection of the connections will be achieved if the gateways and the Call Agents only accept messages for which IP security provided an authentication service. An encryption service adds extra protection against eavesdropping, so third parties can't monitor the connections set up by a given endpoint ๐.
The encryption service will also be requested if the session descriptions are used to carry session keys, as defined in SDP ๐.
ngl, these procedures don't necessarily protect against denial of service attacks by misbehaving gateways or misbehaving Call Agents ๐ญ. what they do give you is a way to identify those misbehaving entities, and then they should be deprived of their authorization through maintenance procedures. no mercy for the bad actors ๐ .
5.1 Protection of Media Connections
MGCP lets the Call Agent give gateways "session keys" that can be used to encrypt the audio messages, which protects against eavesdropping ๐ง๐.
a specific problem with packet networks is "uncontrolled barge-in" ๐. this attack works by directing media packets at the IP address and UDP port used by a connection. if there's no protection in place, the packets get decoded and the signals end up getting played on the "line side" ๐๐ฑ.
a basic protection against this attack is to only accept packets from known sources. however, this tends to clash with RTP principles ๐ซ . it also has two inconveniences: it slows down connection establishment, and it can be fooled by source spoofing.
- To enable the address-based protection, the Call Agent must obtain the source address of the egress gateway and pass it to the ingress gateway. This requires at least one network round trip, and leaves us with a dilemma: either allow the call to proceed without waiting for the round trip to complete, and risk for example "clipping" a remote announcement, or wait for the full round trip and settle for slower call-set-up procedures.
- Source spoofing is only effective if the attacker can obtain valid pairs of source and destination addresses and ports, for example by listening to a fraction of the traffic. To fight source spoofing, one could try to control all access points to the network. But this is, in practice, very hard to achieve ๐ฅฒ.
an alternative to checking the source address is to encrypt and authenticate the packets, using a secret key that is conveyed during the call set-up procedure. this won't slow down call set-up, and it provides strong protection against address spoofing ๐ฅโจ.
6. Packages ๐
as described in Section 2.1.6, packages are the preferred way of extending MGCP ๐. in this section we describe the requirements associated with defining a package.
A package MUST have a unique package name defined. The package name MUST be registered with the IANA, unless it starts with the characters "x-" or "x+", which are reserved for experimental packages ๐งช. Please refer to Appendix C for IANA considerations.
A package MUST also have a version defined, which is simply a non-negative integer. The default and initial version of a package is zero, the next version is one, and so on ๐ข. New package versions MUST be completely backwards compatible, i.e., a new version of a package MUST NOT redefine or remove any of the extensions provided in an earlier version of the package. If such a need arises, a new package name MUST be used instead ๐ โโ๏ธ.
Packages containing signals of type time-out MAY indicate if the "to" parameter is supported for all the time-out signals in the package, as well as the default rounding rules associated with these (see Section 3.2.2.4) โฑ๏ธ. If no such definition is provided, each time-out signal SHOULD provide these definitions.
A package defines one or more of the following extensions ๐งฉ:
- Actions
- BearerInformation
- ConnectionModes
- ConnectionParameters
- DigitMapLetters
- Events and Signals
- ExtensionParameters
- LocalConnectionOptions
- ReasonCodes
- RestartMethods
- Return codes
For each of the above types of extensions supported by the package, the package definition MUST contain a description of the extension, as defined in the following sections. Please note that package extensions, just like any other extension, MUST adhere to the MGCP grammar ๐.
6.1 Actions
Extension Actions SHALL include:
- The name and encoding of the extension action.
- If the extension action takes any action parameters, then the name, encoding, and possible values of those parameters.
- A description of the operation of the extension action.
- A listing of the actions in this specification the extension can be combined with. If such a listing is not provided, it is assumed that the extension action cannot be combined with any other action in this specification.
- If more than one extension action is defined in the package, then a listing of the actions in the package the extension can be combined with. If such a listing is not provided, it is assumed that the extension action cannot be combined with any other action in the package.
Extension actions defined in two or more different packages SHOULD NOT be used simultaneously, unless very careful consideration has been given to their potential interaction and side-effects ๐โ ๏ธ.
6.2 BearerInformation
BearerInformation extensions SHALL include:
- The name and encoding of the BearerInformation extension.
- The possible values and encoding of those values that can be assigned to the BearerInformation extension.
- A description of the operation of the BearerInformation extension. As part of this description, the default value (if any) if the extension is omitted in an EndpointConfiguration command MUST be defined. It may be necessary to make a distinction between the default value before and after the initial application of the parameter, for example if the parameter retains its previous value once specified, until explicitly altered. If default values are not described, then the extension parameter simply defaults to empty in all EndpointConfiguration commands.
Note that the extension SHALL be included in the result for an AuditEndpoint command auditing the BearerInformation ๐.
6.3 ConnectionModes
Extension Connection Modes SHALL include:
- The name and encoding of the extension connection mode.
- A description of the operation of the extension connection mode.
- A description of the interaction a connection in the extension connection mode will have with other connections in each of the modes defined in this specification. If such a description is not provided, the extension connection mode MUST NOT have any interaction with other connections on the endpoint.
Extension connection modes SHALL NOT be included in the list of modes in a response to an AuditEndpoint for Capabilities, since the package will be reported in the list of packages ๐.
6.4 ConnectionParameters
Extension Connection Parameters SHALL include:
- The name and encoding of the connection parameter extension.
- The possible values and encoding of those values that can be assigned to the connection parameter extension.
- A description of how those values are derived.
Note that the extension connection parameter MUST be included in the result for an AuditConnection command auditing the connection parameters ๐ช.
6.5 DigitMapLetters
Extension Digit Map Letters SHALL include:
- The name and encoding of the extension digit map letter(s).
- A description of the meaning of the extension digit map letter(s).
Note that extension DigitMapLetters in a digit map do not follow the normal naming conventions for extensions defined in packages. More specifically, the package name and slash ("/") will not be part of the extension name, which forms a flat and limited name space with potential for name clashing ๐ซฃ.
Therefore, a package SHALL NOT define a digit map letter extension whose encoding has already been used in another package. If two packages have used the same encoding for a digit map letter extension, and those two packages are supported by the same endpoint, the result of using that digit map letter extension is undefined ๐ฅ.
Note that although an extension DigitMapLetter does not include the package name prefix and slash ("/") as part of the extension name within a digit map, the package name prefix and slash are included when the event code for the event that matched the DigitMapLetter is reported as an observed event. In other words, the digit map just defines the matching rule(s), but the event is still reported like any other event ๐ฃโจ.
6.6 Events and Signals ๐
Okay bestie, every event/signal definition SHALL include the precise name of it (the code used in MGCP) ๐, a plain text definition โจ, and, when it's appropriate, the precise definition of the corresponding events/signals, like the exact frequencies of audio signals such as dial tones or DTMF tones ๐ถ.
The package description MUST provide, for each event/signal, the following info:
- The description of the event/signal and its purpose, which SHOULD include the actual signal that is generated by the client (e.g., xx ms FSK tone) as well as the resulting user observed result (e.g., Message Waiting light on/off) ๐ก
The event code used for the event/signal.
- The detailed characteristics of the event/signal, such as for example frequencies and amplitude of audio signals, modulations and repetitions. Such details may be country specific ๐
- The typical and maximum duration of the event/signal if applicable โฑ๏ธ
- If the signal or event can be applied to a connection (across a media stream), it MUST be indicated explicitly. If no such indication is provided, it is assumed that the signal or event cannot be applied to a connection ๐
For events, the following MUST be provided as well:
- An indication if the event is persistent. By default, events are not persistent - defining events as being persistent is discouraged (see Appendix B for a preferred alternative). Note that persistent events will automatically trigger a Notify when they occur, unless the Call Agent explicitly instructed the endpoint otherwise. This not only violates the normal MGCP model, but also assumes the Call Agent supports the package in question. Such an assumption is unlikely to hold in general ๐
Persistent events are a whole vibe, but not the good kind. Think twice before you define one! ๐
- An indication if there is an auditable event-state associated with the event. By default, events do not have auditable event-states ๐ง
- If event parameters are supported, it MUST be stated explicitly. The precise syntax and semantics of these MUST then be provided (subject to the grammar provided in Appendix A). It SHOULD also be specified whether these parameters apply to RequestedEvents, ObservedEvents, DetectEvents and EventStates. If not specified otherwise, it is assumed that:
- they do not apply to RequestedEvents,
- they do apply to ObservedEvents,
- they apply in the same way to DetectEvents as they do to RequestedEvents for a given event parameter,
- they apply in the same way to EventStates as they do to ObservedEvents for a given event parameter.
- If the event is expected to be used in digit map matching, it SHOULD explicitly state so. Note that only events with single letter or digit parameter codes can do this. See Section 2.1.5 for further details ๐ข
For signals, the following MUST be provided as well:
- The type of signal (OO, TO, BR) ๐๏ธ
- Time-Out signals SHOULD have an indication of the default time-out value. In some cases, time-out values may be variable (if dependent on some action to complete such as out-pulsing digits) โณ
- If signal parameters are supported, it MUST be stated explicitly. The precise syntax and semantics of these MUST then be provided (subject to the grammar provided in Appendix A) ๐งพ
- Time-Out signals may also indicate whether the "to" parameter is supported or not as well as what the rounding rules associated with them are. If omitted from the signal definition, the package-wide definition is assumed (see Section 6). If the package definition did not specify this, rounding rules default to the nearest non-zero second, whereas support for the "to" parameter defaults to "no" for package version zero, and "yes" for package versions one and higher ๐ธ
The following format is RECOMMENDED for defining events and signals in conformance with the above:
------------------------------------------------------------------
| Symbol | Definition | R | S Duration |
|---------|----------------------------|-----|---------------------|
| | | | |
| | | | |
------------------------------------------------------------------
where:
- Symbol indicates the event code used for the event/signal, e.g., "hd".
- Definition gives a brief definition of the event/signal
- R contains an "x" if the event can be detected or one or more of the following symbols:
- "P" if the event is persistent.
- "S" if the events is an event-state that may be audited.
- "C" if the event can be detected on a connection.
- S contains one of the following if it is a signal:
- "OO" if the signal is On/Off signal.
- "TO" if the signal is a Time-Out signal.
- "BR" if the signal is a Brief signal.
- S also contains:
- "C" if the signal can be applied on a connection.
The table SHOULD then be followed by a more comprehensive description of each event/signal defined ๐
6.6.1 Default and Reserved Events ๐ก๏ธ
All packages that contain Time-Out type signals contain the operation failure ("of") and operation complete ("oc") events, irrespective of whether they are provided as part of the package description or not. These events are needed to support Time-Out signals and cannot be overridden in packages with Time-Out signals. They MAY be extended if necessary, however such practice is discouraged ๐ซถ
If a package without Time-Out signals does contain definitions for the "oc" and "of" events, the event definitions provided in the package MAY over-ride those indicated here. Such practice is however discouraged and is purely allowed to avoid potential backwards compatibility problems ๐
It is considered good practice to explicitly mention that the two events are supported in accordance with their default definitions, which are as follows:
------------------------------------------------------------------
| Symbol | Definition | R | S Duration |
|---------|----------------------------|-----|---------------------|
| oc | Operation Complete | x | |
| of | Operation Failure | x | |
------------------------------------------------------------------
Operation complete (oc): The operation complete event is generated when the gateway was asked to apply one or several signals of type TO on the endpoint or connection, and one or more of those signals completed without being stopped by the detection of a requested event such as off-hook transition or dialed digit. The completion report should carry as a parameter the name of the signal that came to the end of its live time, as in:
O: G/oc(G/rt)
In this case, the observed event occurred because the "rt" signal in the "G" package timed out โฐ
If the reported signal was applied on a connection, the parameter supplied will include the name of the connection as well, as in:
O: G/oc(G/rt@0A3F58)
When the operation complete event is requested, it cannot be parameterized with any event parameters. When the package name is omitted (which is discouraged) as part of the signal name, the default package is assumed.
Operation failure (of): The operation failure event is generated when the endpoint was asked to apply one or several signals of type TO on the endpoint or connection, and one or more of those signals failed prior to timing out. The completion report should carry as a parameter the name of the signal that failed, as in:
O: G/of(G/rt)
In this case a failure occurred in producing the "rt" signal in the "G" package ๐ฌ
When the reported signal was applied on a connection, the parameter supplied will include the name of the connection as well, as in:
O: G/of(G/rt@0A3F58)
When the operation failure event is requested, event parameters can not be specified. When the package name is omitted (which is discouraged), the default package name is assumed.
6.7 ExtensionParameters ๐งฉ
Extension parameter extensions SHALL include:
- The name and encoding of the extension parameter.
- The possible values and encoding of those values that can be assigned to the extension parameter.
- For each of the commands defined in this specification, whether the extension parameter is Mandatory, Optional, or Forbidden in requests as well as responses. Note that extension parameters SHOULD NOT normally be mandatory ๐ โโ๏ธ
- A description of the operation of the extension parameter. As part of this description the default value (if any) if the extension is omitted in a command MUST be defined. It may be necessary to make a distinction between the default value before and after the initial application of the parameter, for example if the parameter retains its previous value once specified, until explicitly altered. If default values are not described, then the extension parameter simply defaults to empty in all commands ๐
- Whether the extension can be audited in AuditEndpoint and/or AuditConnection as well as the values returned. If nothing is specified, then auditing of the extension parameter can only be done for AuditEndpoint, and the value returned SHALL be the current value for the extension. Note that this may be empty ๐
6.8 LocalConnectionOptions ๐๏ธ
LocalConnectionOptions extensions SHALL include:
- The name and encoding of the LocalConnectionOptions extension.
- The possible values and encoding of those values that can be assigned to the LocalConnectionOptions extension.
- A description of the operation of the LocalConnectionOptions extension. As part of this description the following MUST be specified:
- The default value (if any) if the extension is omitted in a CreateConnection command.
- The default value if omitted in a ModifyConnection command. This may be to simply retain the previous value (if any) or to apply the default value. If nothing is specified, the current value is retained if possible.
- If Auditing of capabilities will result in the extension being returned, then a description to that effect as well as with what possible values and their encoding (note that the package itself will always be returned). If nothing is specified, the extension SHALL NOT be returned when auditing capabilities ๐
Also note, that the extension MUST be included in the result for an AuditConnection command auditing the LocalConnectionOptions ๐
6.9 Reason Codes ๐ฆ
Extension reason codes SHALL include:
- The number for the reason code. The number MUST be in the range 800 to 899 ๐ข
- A description of the extension reason code including the circumstances that leads to the generation of the reason code. Those circumstances SHOULD be limited to events caused by another extension defined in the package to ensure the recipient will be able to interpret the extension reason code correctly ๐ง
Note that the extension reason code may have to be provided in the result for an AuditEndpoint command auditing the reason code โจ
6.10 RestartMethods ๐โจ
okay so, Extension Restart Methods SHALL include: ๐
- The name and encoding for the restart method. ๐ท๏ธ
- A description of the restart method, including the circumstances that leads to the generation of the restart method. Those circumstances SHOULD be limited to events caused by another extension defined in the package, so the recipient will be able to interpret the extension restart method correctly. ๐ง
- An indication of whether the RestartDelay parameter is to be used with the extension. If nothing is specified, it is assumed that it is not to be used. In that case, RestartDelay MUST be ignored if present. ๐
- If the restart method defines a service state, the description MUST explicitly state and describe this. In that case, the extension restart method can then be provided in the result for an AuditEndpoint command auditing the restart method. ๐
6.11 Return Codes ๐
okay this one is giving the same energy ๐ Extension Return Codes SHALL include:
- The number for the extension return code. The number MUST be in the range 800 to 899. ๐ข
- A description of the extension return code, including the circumstances that leads to the generation of the extension return code. Those circumstances SHOULD be limited to events caused by another extension defined in the package, so the recipient will be able to interpret the extension return code correctly. ๐ซถ
7. Versions and Compatibility ๐ธ
7.1 Changes from RFC 2705 ๐ฆ
bestie, RFC 2705 dropped in October 1999 as the last update of draft version 0.5 ๐ฐ๏ธ This updated document benefits from further implementation experience, so it's basically the glow-up edition โจ The main changes from RFC 2705 are:
- Several clarifications, editorial changes, and resolution of known inconsistencies. ๐งน
- Firmed up specification language in accordance with RFC 2119, and added an RFC 2119 conventions section. ๐
- Clarified behavior of mixed wild-carding in endpoint names. ๐
- Deleted the naming requirement about having the first term identify the physical gateway when the gateway consists of multiple physical gateways. Also added recommendations on wild-carding naming usage from the right only, as well as mixed wildcard usage. ๐ซ
- Clarified that synonymous forms and values for endpoint names are not freely interchangeable. ๐
- Allowed IPv6 addresses in endpoint names. ๐
- Clarified Digit Map matching rules. ๐ข
- Added missing semantics for symbols used in digit maps. โ๏ธ
- Added Timer T description in Digit Maps. โฑ๏ธ
- Added recommendation to support digit map sizes of at least 2048 bytes per endpoint. ๐
- Clarified use of wildcards in several commands. ๐ฏ
- Event and Signal Parameters formally defined for events and signals. ๐๏ธ
- Persistent events now allowed in base MGCP protocol. ๐
- Added additional detail on connection wildcards. ๐
- Clarified behavior of loopback and continuity test connection modes for mixing and multiple connections in those modes. ๐
- Modified BearerInformation to be conditional optional in the EndpointConfiguration command. ๐งฉ
- Clarified "swap audio" action operation for one specific scenario and noted that operation for other scenarios is undefined. ๐
- Added recommendation that all implementations support PCMU encoding for interoperability. ๐ค
- Changed Bandwidth LocalConnectionOptions value from excluding to including overhead from the IP layer and up, for consistency with SDP. ๐ถ
- Clarified that mode of second connection in a CreateConnection command will be set to "send/receive". โ๏ธ
- Type of service default changed to zero. 0๏ธโฃ
- Additional detail on echo cancellation, silence suppression, and gain control. Also added recommendation for Call Agents not to specify handling of echo cancellation and gain control. ๐๏ธ
- Added requirement for a connection to have a RemoteConnectionDescriptor in order to use the "network loopback" and "network continuity test" modes. ๐
- Removed procedures and specification for NAS's (will be provided as package instead). ๐ฆ
- Removed procedures and specification for ATM (will be provided as package instead). ๐ฆ
- Added missing optional NotifiedEntity parameter to the DeleteConnection (from the Call Agent) MGCI command. ๐งท
- Added optional new MaxMGCPDatagram RequestedInfo code for AuditEndpoint to enable auditing of maximum size of MGCP datagrams supported. ๐จ
- Added optional new PackageList RequestedInfo code for AuditEndpoint to enable auditing of packages with a package version number. PackageList parameter also allowed with return code 518 (unsupported package). ๐
- Added missing attributes in Capabilities. ๐งพ
- Clarified that at the expiration of a non-zero restart delay, an updated RestartInProgress should be sent. Also clarified that a new NotifiedEntity can only be returned in response to a RestartInProgress command. ๐
- Added Response Acknowledgement response (return code 000) and included it in the three-way handshake. ๐ค
- ResponseAck parameter changed to be allowed in all commands. ๐
- Added return codes 101, 405, 406, 407, 409, 410, 503, 504, 505, 506, 507, 508, 509, 533, 534, 535, 536, 537, 538, 539, 540, 541, and defined return codes in range 800-899 to be package specific return codes. Additional text provided for some return codes, and additional detail on how to handle unknown return codes added. ๐งฏ
- Added reason codes 903, 904, 905, and defined reason codes 800-899 to be package specific reason codes. ๐ท๏ธ
- Added section clarifying codec negotiation procedure. ๐ถ
- Clarified that resource reservation parameters in a ModifyConnection command default to the current value used. ๐๏ธ
- Clarified that connection mode is optional in ModifyConnection commands. ๐
- Corrected LocalConnectionDescriptor to be optional in response to CreateConnection commands (in case of failure). ๐ ๏ธ
- Clarified that quoted-strings are UTF-8 encoded, and the interchangeability of quoted strings and unquoted strings. ๐ค
- Clarified that Transaction Identifiers are compared as numerical values. ๐ข
- Clarified bit-ordering for Type Of Service LocalConnectionOptions. ๐งฎ
- Clarified the use of RequestIdentifier zero. 0๏ธโฃ
- Added example sections for commands, responses, and some call flows. ๐
- Corrected usage of and requirements for SDP to be strictly RFC 2327 compliant. ๐
- Added requirement that all MGCP implementations must support MGCP datagrams up to at least 4000 bytes. Also added new section on Maximum Datagram Size, Fragmentation and reassembly. ๐งฉ
- Generalized piggybacking retransmission scheme to only state underlying requirements to be satisfied. ๐
- Clarified the section on computing retransmission timers. โฒ๏ธ
- Clarified operation of long-running transactions, including provisional responses, retransmissions, and failures. ๐โโ๏ธ
- Enhanced description of provisional responses and interaction with three-way handshake. ๐ซถ
- Enhanced description of fail-over and the role of "notified entity". An empty "notified entity" has been allowed, although strongly discouraged. ๐จ
- Clarified retransmission procedure and removed "wrong key" considerations from it. Also fixed inconsistencies between Max1 and Max2 retransmission boundaries and the associated flow diagram. ๐
- Updated domain name resolution for retransmission procedure to incur less overhead when multiple endpoints are retransmitting. ๐
- Removed requirement for in-order delivery of NotificationRequests response and Notify commands. Notify commands are still delivered in-order. ๐ฌ
- Clarified that activating an embedded Notification Request does not clear the list of ObservedEvents. ๐
- Defined interactions between disconnected state and notification state. ๐
- Added section on transactional semantics. ๐งพ
- Defined gateway behavior when multiple interacting transactions are received. ๐ฆ
- Additional details provided on service states. Clarified relationship between endpoint service states, restart methods, and associated processing of commands. ๐งฉ
- Clarified operation for transitioning from "restart procedure" to "disconnected state". ๐
- Allowed auditing commands and responses to bypass the "restart" and "disconnected" procedures. ๐ช
- Clarified operation of "disconnected procedure" and in particular the operation of piggy-backed "disconnected" RestartInProgress messages. ๐จ
- Added option to aggregate "disconnected" RestartInProgress messages under certain conditions to reduce message volume. ๐
- Defined additional behavior for endpoints wishing to send commands while in the "disconnected" state. ๐ค
- Added new section on Load Control in General, which includes two new error codes (101 and 409) to handle overload. ๐ง
- Deleted the "Proposed MoveConnection command". ๐๏ธ
- Removed packages from protocol specification (will be provided in separate documents instead). ๐ฆ
- Package concept formally extended to be the primary extension mechanism, now allowing extensions for the following to be defined in packages as well: ๐
- BearerInformation
- LocalConnectionOptions
- ExtensionParameters
- Connection Modes
- Actions
- Digit Map Letters
- Connection Parameters
- Restart Methods
- Reason Codes
- Return Codes
- Requirements and suggested format for package definitions added. ๐
- Defined "operation complete" and "operation failure" events to be automatically present in packages with Time-Out signals. โ
- Deleted list of differences that were prior to RFC 2705. ๐งฝ
- Added Base Package to deal with quarantine buffer overflow, ObservedEvents overflow, embedded NotificationRequest failure, and to enable events to be requested persistently. A new "Message" command is included as well. ๐ฌ
- IANA registration procedures for packages and other extensions added. ๐๏ธ
- Updated grammar to fix known errors and support new extensions in a backwards compatible manner. Added new (optional) PackageList and MaxMGCPDatagram for auditing. Changed explicit white space rules in some productions to make grammar more consistent. โ๏ธ
- Connection Mode interaction table added. ๐งญ
- Added additional detail on virtual endpoint naming conventions. Also added suggested gateway endpoint convention and a "Range Wildcard" option to the Endpoint Naming Conventions. ๐ท๏ธ
8. Security Considerations ๐
Security issues are discussed in section 5. ๐จ
9. Acknowledgements ๐
Huge thank-yous go to the authors of the original MGCP 1.0 spec: Mauricio Arango, Andrew Dugan, Isaac Elliott, Christian Huitema, and Scott Picket. They did the hard early work ๐ซถ
We also owe a big shoutout to the many reviewers who gave feedback on the design of SGCP and then MGCP, especially Sankar Ardhanari, Francois Berard, David Auerbach, Bob Biskner, David Bukovinsky, Charles Eckel, Mario Edini, Ed Guy, Barry Hoffner, Jerry Kamitses, Oren Kudevitzki, Rajesh Kumar, Troy Morley, Dave Oran, Jeff Orwick, John Pickens, Lou Rubin, Chip Sharp, Paul Sijben, Kurt Steinbrenner, Joe Stone, and Stuart Wray. Iconic behaviour ๐
Version 0.1 of MGCP was heavily inspired by the "Internet Protocol Device Control" (IPDC) work done by the Technical Advisory Committee set up by Level 3 Communications. Whole chunks of text were pulled from the IP Connection Control protocol, the IP Media Control protocol, and IP Device Management. The authors also want to recognise the contributions to those protocols from Ilya Akramovich, Bob Bell, Dan Brendes, Peter Chung, John Clark, Russ Dehlinger, Andrew Dugan, Isaac Elliott, Cary FitzGerald, Jan Gronski, Tom Hess, Geoff Jordan, Tony Lam, Shawn Lewis, Dave Mazik, Alan Mikhak, Pete O'Connell, Scott Pickett, Shyamal Prasad, Eric Presworsky, Paul Richards, Dale Skran, Louise Spergel, David Sprague, Raj Srinivasan, Tom Taylor and Michael Thomas. Main character energy for all of them ๐
10. References ๐
- [1] Bradner, S., "The Internet Standards Process -- Revision 3", BCP 9, RFC 2026, October 1996.
- [2] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
- [3] Schulzrinne, H., Casner, S., Frederick, R. and V. Jacobson, "RTP: A Transport Protocol for Real-Time Applications", RFC 1889, January 1996.
- [4] Schulzrinne, H., "RTP Profile for Audio and Video Conferences with Minimal Control", RFC 1890, January 1996.
- [5] Handley, M. and V. Jacobson, "SDP: Session Description Protocol", RFC 2327, April 1998.
- [6] Handley, M., Perkins, C. and E. Whelan, "Session Announcement Protocol", RFC 2974, October 2000.
- [7] Rosenberg, J., Camarillo, G., Johnston, A., Peterson, J., Sparks, R., Handley, M., Schulzrinne, H. and E. Schooler, "Session Initiation Protocol (SIP)", RFC 3261, June 2002.
- [8] Schulzrinne, H., Rao, A. and R. Lanphier, "Real Time Streaming Protocol (RTSP)", RFC 2326, April 1998.
- [9] ITU-T, Recommendation Q.761, "FUNCTIONAL DESCRIPTION OF THE ISDN USER PART OF SIGNALING SYSTEM No. 7", (Malaga-Torremolinos, 1984; modified at Helsinki, 1993).
- [10] ITU-T, Recommendation Q.762, "GENERAL FUNCTION OF MESSAGES AND SIGNALS OF THE ISDN USER PART OF SIGNALING SYSTEM No. 7", (MalagaTorremolinos, 1984; modified at Helsinki, 1993).
- [11] ITU-T, Recommendation H.323 (02/98), "PACKET-BASED MULTIMEDIA COMMUNICATIONS SYSTEMS".
- [12] ITU-T, Recommendation H.225, "Call Signaling Protocols and Media Stream Packetization for Packet Based Multimedia Communications Systems".
- [13] ITU-T, Recommendation H.245 (02/98), "CONTROL PROTOCOL FOR MULTIMEDIA COMMUNICATION".
- [14] Kent, S. and R. Atkinson, "Security Architecture for the Internet Protocol", RFC 2401, November 1998.
- [15] Kent, S. and R. Atkinson, "IP Authentication Header", RFC 2402, November 1998.
- [16] Kent, S. and R. Atkinson, "IP Encapsulating Security Payload (ESP)", RFC 2406, November 1998.
- [17] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", RFC 2234, November 1997.
- [18] Stevens, W. Richard, "TCP/IP Illustrated, Volume 1, The Protocols", Addison-Wesley, 1994.
- [19] Allman, M., Paxson, V. "On Estimating End-to-End Network Path Properties", Proc. SIGCOMM'99, 1999.
- [20] Yergeau, F., "UTF-8, a transformation format of ISO 10646", RFC 2279, January 1998.
- [21] Braden, R., "Requirements for Internet Hosts -- Communication Layers", STD 3, RFC 1122, October 1989.
- [22] Bellcore, "LSSGR: Switching System Generic Requirements for Call Control Using the Integrated Services Digital Network User Part (ISDNUP)", GR-317-CORE, Issue 2, December 1997.
- [23] Narten, T., and Alvestrand H., "Guidelines for Writing an IANA Considerations Section in RFCs", RFC 2434, October 1998.
Appendix A: Formal Syntax Description of the Protocol ๐ง
Here we give a formal description of the protocol syntax, written in the "Augmented BNF for Syntax Specifications" from RFC 2234 ๐ The syntax uses the core rules from RFC 2234, Section 6.1, which we're not repeating here. It also follows RFC 2234's case-sensitivity rules, which means MGCP is case-insensitive (but SDP is not) ๐ค Real talk: ABNF doesn't handle implicit linear white space, so MGCP messages MUST follow the explicit linear white space rules in the grammar below. That said, following general robustness principles, implementers are strongly encouraged to tolerate extra linear white space in the messages they receive ๐ซถ
MGCPMessage = MGCPCommand / MGCPResponse
MGCPCommand = MGCPCommandLine 0*(MGCPParameter) [EOL *SDPinformation]
MGCPCommandLine = MGCPVerb 1*(WSP) transaction-id 1*(WSP)
endpointName 1*(WSP) MGCPversion EOL
MGCPVerb = "EPCF" / "CRCX" / "MDCX" / "DLCX" / "RQNT"
/ "NTFY" / "AUEP" / "AUCX" / "RSIP" / extensionVerb
extensionVerb = ALPHA 3(ALPHA / DIGIT) ; experimental starts with X
transaction-id = 1*9(DIGIT)
endpointName = LocalEndpointName "@" DomainName
LocalEndpointName = LocalNamePart 0*("/" LocalNamePart)
LocalNamePart = AnyName / AllName / NameString
AnyName = "$"
AllName = "*"
NameString = 1*(range-of-allowed-characters)
; VCHAR except "$", "*", "/", "@"
range-of-allowed-characters = %x21-23 / %x25-29 / %x2B-2E
/ %x30-3F / %x41-7E
DomainName = 1*255(ALPHA / DIGIT / "." / "-") ; as defined
/ "#" number ; in RFC 821
/ "[" IPv4address / IPv6address "]" ; see RFC 2373
; Rewritten to ABNF from RFC 821
number = 1*DIGIT
;From RFC 2373
IPv6address = hexpart [ ":" IPv4address ]
IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
; this production, while occurring in RFC2373, is not referenced
; IPv6prefix = hexpart "/" 1*2DIGIT
hexpart = hexseq / hexseq "::" [ hexseq ] / "::" [ hexseq ]
hexseq = hex4 *( ":" hex4)
hex4 = 1*4HEXDIG
MGCPversion = "MGCP" 1*(WSP) 1*(DIGIT) "." 1*(DIGIT)
[1*(WSP) ProfileName]
ProfileName = VCHAR *( WSP / VCHAR)
MGCPParameter = ParameterValue EOL
; Check infoCode if more parameter values defined
; Most optional values can only be omitted when auditing
ParameterValue = ("K" ":" 0*(WSP) [ResponseAck])
/ ("B" ":" 0*(WSP) [BearerInformation])
/ ("C" ":" 0*(WSP) CallId)
/ ("I" ":" 0*(WSP) [ConnectionId])
/ ("N" ":" 0*(WSP) [NotifiedEntity])
/ ("X" ":" 0*(WSP) [RequestIdentifier])
/ ("L" ":" 0*(WSP) [LocalConnectionOptions])
/ ("M" ":" 0*(WSP) ConnectionMode)
/ ("R" ":" 0*(WSP) [RequestedEvents])
/ ("S" ":" 0*(WSP) [SignalRequests])
/ ("D" ":" 0*(WSP) [DigitMap])
/ ("O" ":" 0*(WSP) [ObservedEvents])
/ ("P" ":" 0*(WSP) [ConnectionParameters])
/ ("E" ":" 0*(WSP) ReasonCode)
/ ("Z" ":" 0*(WSP) [SpecificEndpointID])
/ ("Z2" ":" 0*(WSP) SecondEndpointID)
/ ("I2" ":" 0*(WSP) SecondConnectionID)
/ ("F" ":" 0*(WSP) [RequestedInfo])
/ ("Q" ":" 0*(WSP) QuarantineHandling)
/ ("T" ":" 0*(WSP) [DetectEvents])
/ ("RM" ":" 0*(WSP) RestartMethod)
/ ("RD" ":" 0*(WSP) RestartDelay)
/ ("A" ":" 0*(WSP) [Capabilities])
/ ("ES" ":" 0*(WSP) [EventStates])
/ ("PL" ":" 0*(WSP) [PackageList]) ; Auditing only
/ ("MD" ":" 0*(WSP) MaxMGCPDatagram) ; Auditing only
/ (extensionParameter ":" 0*(WSP) [parameterString])
; A final response may include an empty ResponseAck
ResponseAck = confirmedTransactionIdRange
*( "," 0*(WSP) confirmedTransactionIdRange )
confirmedTransactionIdRange = transaction-id ["-" transaction-id]
BearerInformation = BearerAttribute 0*("," 0*(WSP) BearerAttribute)
BearerAttribute = ("e" ":" BearerEncoding)
/ (BearerExtensionName [":" BearerExtensionValue])
BearerExtensionName = PackageLCOExtensionName
BearerExtensionValue = LocalOptionExtensionValue
BearerEncoding = "A" / "mu"
CallId = 1*32(HEXDIG)
; The audit request response may include a list of identifiers
ConnectionId = 1*32(HEXDIG) 0*("," 0*(WSP) 1*32(HEXDIG))
SecondConnectionID = ConnectionId
NotifiedEntity = [LocalName "@"] DomainName [":" portNumber]
LocalName = LocalEndpointName ; No internal structure
portNumber = 1*5(DIGIT)
RequestIdentifier = 1*32(HEXDIG)
LocalConnectionOptions = LocalOptionValue 0*(WSP)
0*("," 0*(WSP) LocalOptionValue 0*(WSP))
LocalOptionValue = ("p" ":" packetizationPeriod)
/ ("a" ":" compressionAlgorithm)
/ ("b" ":" bandwidth)
/ ("e" ":" echoCancellation)
/ ("gc" ":" gainControl)
/ ("s" ":" silenceSuppression)
/ ("t" ":" typeOfService)
/ ("r" ":" resourceReservation)
/ ("k" ":" encryptiondata)
/ ("nt" ":" ( typeOfNetwork /
supportedTypeOfNetwork))
/ (LocalOptionExtensionName
[":" LocalOptionExtensionValue])
Capabilities = CapabilityValue 0*(WSP)
0*("," 0*(WSP) CapabilityValue 0*(WSP))
CapabilityValue = LocalOptionValue
/ ("v" ":" supportedPackages)
/ ("m" ":" supportedModes)
PackageList = pkgNameAndVers 0*("," pkgNameAndVers)
pkgNameAndVers = packageName ":" packageVersion
packageVersion = 1*(DIGIT)
packetizationPeriod = 1*4(DIGIT) ["-" 1*4(DIGIT)]
compressionAlgorithm = algorithmName 0*(";" algorithmName)
algorithmName = 1*(SuitableLCOCharacter)
bandwidth = 1*4(DIGIT) ["-" 1*4(DIGIT)]
echoCancellation = "on" / "off"
gainControl = "auto" / ["-"] 1*4(DIGIT)
silenceSuppression = "on" / "off"
typeOfService = 1*2(HEXDIG) ; 1 hex only for capabilities
resourceReservation = "g" / "cl" / "be"
;encryption parameters are coded as in SDP (RFC 2327)
;NOTE: encryption key may contain an algorithm as specified in RFC 1890
encryptiondata = ( "clear" ":" encryptionKey )
/ ( "base64" ":" encodedEncryptionKey )
/ ( "uri" ":" URItoObtainKey )
/ ( "prompt" ) ; defined in SDP, not usable in MGCP!
encryptionKey = 1*(SuitableLCOCharacter) / quotedString
; See RFC 2045
encodedEncryptionKey = 1*(ALPHA / DIGIT / "+" / "/" / "=")
URItoObtainKey = 1*(SuitableLCOCharacter) / quotedString
typeOfNetwork = "IN" / "ATM" / "LOCAL" / OtherTypeOfNetwork
; Registered with IANA - see RFC 2327
OtherTypeOfNetwork = 1*(SuitableLCOCharacter)
supportedTypeOfNetwork = typeOfNetwork *(";" typeOfNetwork)
supportedModes = ConnectionMode 0*(";" ConnectionMode)
supportedPackages = packageName 0*(";" packageName)
packageName = 1*(ALPHA / DIGIT / HYPHEN) ; Hyphen neither first or last
okay bestie, here's the grammar for the LCO extension names, connection modes, event requests and friends ๐
LocalOptionExtensionName = VendorLCOExtensionName
/ PackageLCOExtensionName
/ OtherLCOExtensionName
VendorLCOExtensionName = "x" ("+"/"-") 1*32(SuitableExtLCOCharacter)
PackageLCOExtensionName = packageName "/"
1*32(SuitablePkgExtLCOCharacter)
; must not start with "x-" or "x+"
OtherLCOExtensionName = 1*32(SuitableExtLCOCharacter)
LocalOptionExtensionValue = (1*(SuitableExtLCOValChar)
/ quotedString)
*(";" (1*(SuitableExtLCOValChar)
/ quotedString))
;Note: No "data" mode.
ConnectionMode = "sendonly" / "recvonly" / "sendrecv"
/ "confrnce" / "inactive" / "loopback"
/ "conttest" / "netwloop" / "netwtest"
/ ExtensionConnectionMode
ExtensionConnectionMode = PkgExtConnectionMode
PkgExtConnectionMode = packageName "/" 1*(ALPHA / DIGIT)
RequestedEvents = requestedEvent 0*("," 0*(WSP) requestedEvent)
requestedEvent = (eventName ["(" requestedActions ")"])
/ (eventName "(" requestedActions ")"
"(" eventParameters ")" )
eventName = [(packageName / "*") "/"]
(eventId / "all" / eventRange
/ "*" / "#") ; for DTMF
["@" (ConnectionId / "$" / "*")]
eventId = 1*(ALPHA / DIGIT / HYPHEN) ; Hyphen neither first nor last
eventRange = "[" 1*(DigitMapLetter / (DIGIT "-" DIGIT) /
(DTMFLetter "-" DTMFLetter)) "]"
DTMFLetter = "A" / "B" / "C" / "D"
requestedActions = requestedAction 0*("," 0*(WSP) requestedAction)
requestedAction = "N" / "A" / "D" / "S" / "I" / "K"
/ "E" "(" EmbeddedRequest ")"
/ ExtensionAction
ExtensionAction = PackageExtAction
PackageExtAction = packageName "/" Action ["(" ActionParameters ")"]
Action = 1*ALPHA
ActionParameters = eventParameters ; May contain actions
;NOTE: Should tolerate different order when receiving, e.g., for NCS.
EmbeddedRequest = ( "R" "(" EmbeddedRequestList ")"
["," 0*(WSP) "S" "(" EmbeddedSignalRequest ")"]
["," 0*(WSP) "D" "(" EmbeddedDigitMap ")"] )
/ ( "S" "(" EmbeddedSignalRequest ")"
["," 0*(WSP) "D" "(" EmbeddedDigitMap ")"] )
/ ( "D" "(" EmbeddedDigitMap ")" )
EmbeddedRequestList = RequestedEvents
EmbeddedSignalRequest = SignalRequests
EmbeddedDigitMap = DigitMap
SignalRequests = SignalRequest 0*("," 0*(WSP) SignalRequest )
SignalRequest = eventName [ "(" eventParameters ")" ]
eventParameters = eventParameter 0*("," 0*(WSP) eventParameter)
eventParameter = eventParameterValue
/ eventParameterName "=" eventParameter
/ eventParameterName "(" eventParameters ")"
eventParameterString = 1*(SuitableEventParamCharacter)
eventParameterName = eventParameterString
eventParameterValue = eventParameterString / quotedString
DigitMap = DigitString / "(" DigitStringList ")"
DigitStringList = DigitString 0*( "|" DigitString )
DigitString = 1*(DigitStringElement)
DigitStringElement = DigitPosition ["."]
DigitPosition = DigitMapLetter / DigitMapRange
; NOTE "X" is now included
DigitMapLetter = DIGIT / "#" / "*" / "A" / "B" / "C" / "D" / "T"
/ "X" / ExtensionDigitMapLetter
ExtensionDigitMapLetter = "E" / "F" / "G" / "H" / "I" / "J" / "K"
/ "L" / "M" / "N" / "O" / "P" / "Q" / "R"
/ "S" / "U" / "V" / "W" / "Y" / "Z"
; NOTE "[x]" is now allowed
DigitMapRange = "[" 1*DigitLetter "]"
DigitLetter = *((DIGIT "-" DIGIT) / DigitMapLetter)
ObservedEvents = SignalRequests
EventStates = SignalRequests
ConnectionParameters = ConnectionParameter
0*( "," 0*(WSP) ConnectionParameter )
ConnectionParameter = ( "PS" "=" packetsSent )
/ ( "OS" "=" octetsSent )
/ ( "PR" "=" packetsReceived )
/ ( "OR" "=" octetsReceived )
/ ( "PL" "=" packetsLost )
/ ( "JI" "=" jitter )
/ ( "LA" "=" averageLatency )
/ ( ConnectionParameterExtensionName
"=" ConnectionParameterExtensionValue )
packetsSent = 1*9(DIGIT)
octetsSent = 1*9(DIGIT)
packetsReceived = 1*9(DIGIT)
octetsReceived = 1*9(DIGIT)
packetsLost = 1*9(DIGIT)
jitter = 1*9(DIGIT)
averageLatency = 1*9(DIGIT)
ConnectionParameterExtensionName = VendorCPExtensionName
/ PackageCPExtensionName
VendorCPExtensionName = "X" "-" 2*ALPHA
PackageCPExtensionName = packageName "/" CPName
CPName = 1*(ALPHA / DIGIT / HYPHEN)
ConnectionParameterExtensionValue = 1*9(DIGIT)
MaxMGCPDatagram = 1*9(DIGIT)
ReasonCode = 3DIGIT
[1*(WSP) "/" packageName] ; Only for 8xx
[WSP 1*(%x20-7E)]
SpecificEndpointID = endpointName
SecondEndpointID = endpointName
RequestedInfo = infoCode 0*("," 0*(WSP) infoCode)
infoCode = "B" / "C" / "I" / "N" / "X" / "L" / "M" / "R" / "S"
/ "D" / "O" / "P" / "E" / "Z" / "Q" / "T" / "RC" / "LC"
/ "A" / "ES" / "RM" / "RD" / "PL" / "MD" / extensionParameter
QuarantineHandling = loopControl / processControl
/ (loopControl "," 0*(WSP) processControl )
loopControl = "step" / "loop"
processControl = "process" / "discard"
DetectEvents = SignalRequests
RestartMethod = "graceful" / "forced" / "restart" / "disconnected"
/ "cancel-graceful" / extensionRestartMethod
extensionRestartMethod = PackageExtensionRM
PackageExtensionRM = packageName "/" 1*32(ALPHA / DIGIT / HYPHEN)
RestartDelay = 1*6(DIGIT)
extensionParameter = VendorExtensionParameter
/ PackageExtensionParameter
/ OtherExtensionParameter
VendorExtensionParameter = "X" ("-"/"+") 1*6(ALPHA / DIGIT)
PackageExtensionParameter = packageName "/"
1*32(ALPHA / DIGIT / HYPHEN)
; must not start with "x-" or x+"
OtherExtensionParameter = 1*32(ALPHA / DIGIT / HYPHEN)
;If first character is a double-quote, then it is a quoted-string
parameterString = (%x21 / %x23-7F) *(%x20-7F) ; first and last must not
; be white space
/ quotedString
MGCPResponse = MGCPResponseLine 0*(MGCPParameter)
*2(EOL *SDPinformation)
MGCPResponseLine = responseCode 1*(WSP) transaction-id
[1*(WSP) "/" packageName] ; Only for 8xx
[WSP responseString] EOL
responseCode = 3DIGIT
responseString = *(%x20-7E)
SuitablePkgExtLCOCharacter = SuitableLCOCharacter
SuitableExtLCOCharacter = DIGIT / ALPHA / "+" / "-" / "_" / "&"
/ "!" / "'" / "|" / "=" / "#" / "?"
/ "." / "$" / "*" / "@" / "[" / "]"
/ "^" / "`" / "{" / "}" / "~"
SuitableLCOCharacter = SuitableExtLCOCharacter / "/"
SuitableExtLCOValChar = SuitableLCOCharacter / ":"
; VCHAR except """, "(", ")", ",", and "="
SuitableEventParamCharacter = %x21 / %x23-27 / %x2A-2B
/ %x2D-3C / %x3E-7E
; NOTE: UTF8 encoded
quotedString = DQUOTE 0*(quoteEscape / quoteChar) DQUOTE
quoteEscape = DQUOTE DQUOTE
quoteChar = (%x00-21 / %x23-FF)
EOL = CRLF / LF
HYPHEN = "-"
; See RFC 2327 for proper SDP grammar instead.
SDPinformation = SDPLine CRLF *(SDPLine CRLF) ; see RFC 2327
SDPLine = 1*(%x01-09 / %x0B / %x0C / %x0E-FF) ; for proper def.
Appendix B: Base Package
Package name: B Version: 0
okay so the base package is the OG starter pack ๐ง The MGCP specification defines a base package that holds a set of events and extension parameters that are of general use to the protocol. It's not required, but it is highly RECOMMENDED to support this package, because it provides important functionality for the base protocol โจ
B.1 Events
The table below lists the events:
------------------------------------------------------------------
| Symbol | Definition | R | S Duration |
|---------|----------------------------|-----|---------------------|
| enf(##) | embedded RQNT failure | x | |
| oef | observed events full | x | |
| qbo | quarantine buffer overflow | x | |
------------------------------------------------------------------
The events are defined as follows:
Embedded NotificationRequest failure (enf)
The Embedded NotificationRequest Failure (enf) event is generated when an embedded Notification Request failure occurs ๐ When the event is requested, it should be as part of the Embedded NotificationRequest itself. When the event is reported, it may be parameterized with an error code (see Section 2.4) detailing the error that occurred. When requested, it cannot be parameterized ๐
Observed events full (oef)
The event is generated when the endpoint is unable to accumulate any more events in the list of ObservedEvents. If this event occurs, and it is not used to trigger a Notify, subsequent events that should have been added to the list will be lost. not the events getting dropped ๐ญ
Quarantine buffer overflow (qbo)
The event is generated when the quarantine buffer overflows and one or more events have been lost ๐ซถ
B.2 Extension Parameters
B.2.1 PersistentEvents โจ
Okay so PersistentEvents is a list of events that the gateway is requested to detect and report persistently ๐ The parameter is optional, but you can provide it in any command where DetectEvents can be provided. Its initial default value is empty ๐ธ If you leave it out of a command, it keeps its current value ๐ซถ If you do provide it, it completely replaces the current value, no merging ๐
Providing an event in this list is similar to defining that event as persistent, but it's the preferable move ๐ฆ The current list of PersistentEvents implicitly applies to the current NotificationRequests as well as the subsequent ones, however no glare detection etc. will be performed (same as DetectEvents) ๐ If an event in this list also shows up in a RequestedEvents list, the action and event parameters from RequestedEvents replace the ones tied to that event in PersistentEvents, but only for the life of that RequestedEvents list. After that, the PersistentEvents action and event parameters are restored ๐ฅ Events with event states requested through this parameter will be included in the list of EventStates if audited ๐
PersistentEvents can also be used to detect events on connections. Using the "all connections" wildcard is straightforward, but using PersistentEvents with one or more specific connections needs to be considered carefully ๐ Once the connection in question is deleted, a subsequent NotificationRequest without a new PersistentEvents value will fail (error code 515 - incorrect connection-id, is RECOMMENDED), because it implicitly refers to the deleted connection ๐
The parameter generates the relevant error codes from the base protocol, e.g., error code 512 if an unknown event is specified ๐ง
The PersistentEvents parameter can be audited, in which case it returns its current value โจ Auditing of RequestedEvents is not affected by this extension, so events specified in this list are not automatically reported when you audit RequestedEvents ๐
The parameter name for PersistentEvents is "PR", and it's defined by this production:
PersistentEvents = "PR" ":" 0*WSP [RequestedEvents]
Here's how it looks in action:
B/PR: L/hd(N), L/hf(N), L/hu(N), B/enf, B/oef, B/qbo
This tells the endpoint to persistently detect and report off-hook, hook-flash, and on-hook ๐ It also tells it to persistently detect and report Embedded Notification Request failure, Observed events full, and Quarantine buffer overflow ๐
B.2.2 NotificationState
NotificationState is a RequestedInfo parameter that you can audit with the AuditEndpoint command ๐ฆ It tells you whether the endpoint is in the notification state or not ๐
The parameter is forbidden in any command. In responses, it's a valid response parameter for AuditEndpoint only ๐ โโ๏ธ
It's defined by the following grammar:
NotificationState = "NS" ":" 0*WSP NotificationStateValue
NotificationStateValue = "ns" / "ls" / "o"
To request it as part of an audit, include the parameter code in RequestedInfo, like this:
F: B/NS
The response parameter will contain the value "ns" if the endpoint is in the "notification state". It'll contain "ls" if the endpoint is in the "lockstep state" (basically, waiting for an RQNT after a response to a NTFY has been received when operating in "step" mode) ๐ Otherwise it'll be "o". For example:
B/NS: ns
B.3 Verbs ๐งโโ๏ธ
MGCP packages aren't meant to define new commands, but this is an exception, because it adds an important general capability that's currently missing: the ability for the gateway to send a generic message to the Call Agent ๐ฃ
Here's the definition of the new command:
ReturnCode
<-- Message(EndpointId
[, ...])
EndpointId is the name for the endpoint(s) in the gateway that's issuing the Message command. The identifier MUST be a fully qualified endpoint identifier, including the domain name of the gateway ๐ The local part of the endpoint name MUST NOT use the "any of" wildcard ๐ โโ๏ธ
The only parameter specified in the Message command definition is the EndpointId. However, extensions are expected to define additional parameters for use with the Message command ๐ Such extensions MUST NOT alter or otherwise interfere with the normal operation of the basic MGCP protocol. They may, however, define additional capabilities above and beyond what the basic MGCP protocol provides. For example, an extension that lets the gateway audit the packages supported by the Call Agent could be defined. Using the Message command as an alternative way of reporting observed events, though, would be illegal, because that would alter the normal MGCP protocol behavior ๐ซ
To avoid interfering with normal MGCP operation, a lack of a response to the Message command MUST NOT lead the endpoint to become disconnected. The endpoint(s) MUST be prepared to handle this transparently and continue normal processing unaffected ๐ซถ
If the endpoint(s) receive a response indicating that the Call Agent does not support the Message command, the endpoint(s) MUST NOT send a Message command again until the current "notified entity" has changed. Similarly, if the endpoint(s) receive a response indicating that the Call Agent does not support one or more parameters in the Message command, the endpoint(s) MUST NOT send a Message command with those parameters again until the current "notified entity" has changed ๐
The Message command is encoded as MESG, like in this example:
MESG 1200 aaln/1@rgw.whatever.net MGCP 1.0
Appendix C: IANA Considerations ๐ท
C.1 New MGCP Package Sub-Registry
The IANA has set up a new sub-registry for MGCP packages under http://www.iana.org/assignments/mgcp-packages ๐
Packages can be registered with the IANA using the following procedure ๐
The package MUST have a unique string name, which MUST NOT start with the two characters "x-" or "x+" ๐ซ
The package title, name, and version (zero assumed by default) MUST be registered with IANA, along with a reference to the document that describes the package. The document MUST have a stable URL and MUST be contained on a public web server ๐
Packages may define one or more Extension Digit Map Letters. These come from a limited, flat name space, though, so to prevent name clashing, IANA SHALL NOT register a package that defines an Extension Digit Map Letter already defined in another package registered by IANA ๐ค To make this easier, such packages SHALL contain the line "Extension Digit Map Letters: " followed by a list of the Extension Digit Map Letters defined in the package, at the beginning of the package definition โจ
A contact name, e-mail address, and postal address for the package MUST be provided. The contact information SHALL be updated by the defining organization as necessary ๐ฎ
Finally, before registering a package, the IANA MUST have a designated expert [23] review the package. The expert reviewer will send e-mail to the IANA about the overall review determination ๐ต๏ธโโ๏ธ
C.2 New MGCP Package
This document defines a new MGCP Base Package in Appendix B, which has been registered by IANA ๐
C.3 New MGCP LocalConnectionOptions Sub-Registry
The IANA has set up a new sub-registry for MGCP LocalConnectionOptions under http://www.iana.org/assignments/mgcp-localconnectionoptions ๐๏ธ
Packages are the preferred extension mechanism. For backwards compatibility, though, local connection options beyond those provided in this specification can be registered with IANA ๐ Each such local connection option MUST have a unique string name, which MUST NOT start with "x-" or "x+". The local connection option field name and encoding name MUST be registered with IANA, along with a reference to the document that describes the local connection option. The document MUST have a stable URL and MUST be contained on a public web server ๐
A contact name, e-mail address, and postal address for the local connection option MUST be provided. The contact information SHALL be updated by the defining organization as necessary ๐ฎ
Finally, before registering a LocalConnectionOption, the IANA MUST have a designated expert [23] review the LocalConnectionOption. The expert reviewer will send e-mail to the IANA about the overall review determination ๐
Appendix D: Mode Interactions โจ
okay so an MGCP endpoint can set up one or more media streams ๐ง these streams are either incoming (coming from a remote endpoint) or outgoing (generated by the handset microphone). the "connection mode" parameter decides the direction and generation of these streams. when there's only one connection, it's super straightforward: the handset plays the incoming stream through the speaker and makes the outgoing stream from the mic signal, depending on the mode parameter ๐
but when several connections are set up on one endpoint, there can be a LOT of incoming and outgoing streams ๐ญ depending on the connection mode, these streams can interact in different ways with each other and with the streams going to and from the handset. it's giving chaotic, but it's organised chaos ๐
The table below describes how different connections SHALL be mixed when one or more connections are concurrently "active". an active connection here means a connection that's in one of these modes:
- "send/receive"
- "send only"
- "receive only"
- "conference"
Connections in "network loopback", "network continuity test", or "inactive" modes are not affected by connections in the "active" modes ๐ฆ the table uses these conventions:
- Ai is the incoming media stream from Connection A
- Bi is the incoming media stream from Connection B
- Hi is the incoming media stream from the Handset Microphone
- Ao is the outgoing media stream to Connection A
- Bo is the outgoing media stream to Connection B
- Ho is the outgoing media stream to the Handset earpiece
- NA means no stream whatsoever (assuming no signals are applied on the connection)
"netw" in the table below means either "netwloop" or "netwtest" mode ๐ธ
-------------------------------------------------------------
| | Connection A Mode |
| |-----------------------------------------------------
| |sendonly|recvonly|sendrecv|confrnce|inactive| netw |
|-------|-----------------------------------------------------|
| |Send | Ao=Hi | Ao=NA | Ao=Hi | Ao=Hi | Ao=NA | Ao=Ai |
|C|only | Bo=Hi | Bo=Hi | Bo=Hi | Bo=Hi | Bo=Hi | Bo=Hi |
|o| | Ho=NA | Ho=Ai | Ho=Ai | Ho=Ai | Ho=NA | Ho=NA |
|n|-----------------------------------------------------------
|n|recv | |Ao=NA |Ao=Hi |Ao=Hi | Ao=NA | Ao=Ai |
|e|only | |Bo=NA |Bo=NA |Bo=NA | Bo=NA | Bo=NA |
|c| | |Ho=Ai+Bi|Ho=Ai+Bi|Ho=Ai+Bi| Ho=Bi | Ho=Bi |
|t|-----------------------------------------------------------|
|i|send | | |Ao=Hi |Ao=Hi | Ao=NA | Ao=Ai |
|o|recv | | |Bo=Hi |Bo=Hi | Bo=Hi | Bo=Hi |
|n| | | |Ho=Ai+Bi|Ho=Ai+Bi| Ho=Bi | Ho=Bi |
| |-----------------------------------------------------------|
|B|conf | | | |Ao=Hi+Bi| Ao=NA | Ao=Ai |
| |rnce | | | |Bo=Hi+Ai| Bo=Hi | Bo=Hi |
|M| | | | |Ho=Ai+Bi| Ho=Bi | Ho=Bi |
|o|-----------------------------------------------------------|
|d|Inac | | | | | Ao=NA | Ao=Ai |
|e|tive | | | | | Bo=NA | Bo=NA |
| | | | | | | Ho=NA | Ho=NA |
| |-----------------------------------------------------------|
| |netw | | | | | | Ao=Ai |
| | | | | | | | Bo=Bi |
| | | | | | | | Ho=NA |
-------------------------------------------------------------
if there are three or more "active" connections, they still interact as the table above defines, with the outgoing media streams mixed for each interaction (the union of all streams) ๐ but if internal resources run out and the streams can't be mixed, the gateway MUST return an error (error code 403 or 502, not enough resources, are RECOMMENDED) ๐จ that's the bit to remember, bestie ๐ญ
Appendix E: Endpoint Naming Conventions ๐ง
the following sections give some RECOMMENDED endpoint naming conventions ๐
E.1 Analog Access Line Endpoints
the string "aaln" should be used as the first term in a local endpoint name for analog access line endpoints ๐ the terms after "aaln" should follow the physical hierarchy of the gateway. so if the gateway has a bunch of RJ11 ports, the local endpoint name could look like this:
aaln/#
where "#" is the number of the analog line (RJ11 port) on the gateway.
or, the gateway might have several physical plug-in units, each holding some RJ11 ports ๐ in that case, the local endpoint name might look like this:
aaln/<unit #>/#
where <unit #> is the number of the plug-in unit in the gateway and "#" is the number of the analog line (RJ11 port) on that unit. Leading zeroes MUST NOT be used in any of the numbers ("#") above ๐
E.2 Digital Trunks
the string "ds" should be used for the first term of digital endpoints, with a naming convention that follows the physical and digital hierarchy, like this:
ds/<unit-type1>-<unit #>/<unit-type2>-<unit #>/.../<channel #>
where <unit-type> identifies the particular hierarchy level. some example values of <unit-type> are "s", "su", "oc3", "ds3", "e3", "ds2", "e2", "ds1", and "e1", where "s" means a slot number and "su" means a sub-unit within a slot ๐ Leading zeroes MUST NOT be used in any of the numbers ("#") above.
the <unit #> is a decimal number used to reference a particular instance of a <unit-type> at that level of the hierarchy. the number of levels and what they're called depends on the physical hierarchy inside the media gateway ๐
E.3 Virtual Endpoints
another kind of endpoint isn't tied to a physical interface (like an analog or digital one) ๐ this is called a virtual endpoint, and it's often used to represent DSP resources that give the endpoint some capability. examples are announcement, IVR, or conference bridge devices ๐๏ธ these devices may have multiple DSP function instances, so one possible naming convention is:
<virtual-endpoint-type>/<endpoint-#>
where <virtual-endpoint-type> can be a string representing the type of endpoint (like "ann" for an announcement server or "cnf" for a conference server), and <endpoint-#> identifies a particular virtual endpoint within the device. Leading zeroes MUST NOT be used in the number ("#") above. if the server's physical hierarchy includes plug-in DSP cards, another level of hierarchy in the local endpoint name may be used to describe the plug-in unit ๐ฆ
a virtual endpoint may be created as the result of using the "any of" wildcard. similarly, a virtual endpoint may stop existing once the last connection on it is deleted โจ the definition of the virtual endpoint MUST detail both of these aspects.
when a <virtual-endpoint-type> creates and deletes virtual endpoints automatically, there will be cases where no virtual endpoints exist at the time a RestartInProgress command needs to be issued ๐ฅบ in those cases, the gateway SHOULD simply use the "all of" wildcard in place of any specific <endpoint-#>, like this:
ann/*@mygateway.whatever.net
if the RestartInProgress command refers to all endpoints in the gateway (virtual or not), the <virtual-endpoint-id> can be left out, like this:
*@mygateway.whatever.net
Commands received by the gateway still have to refer to an actual endpoint (possibly one created by that very command using the "any of" wildcard) in order for the command to be processed ๐ซ
E.4 Media Gateway
MGCP only defines operation on endpoints in a media gateway ๐ it can be beneficial to define an endpoint that represents the gateway itself, as opposed to the endpoints the gateway manages. implementations that want to do this should use the local endpoint name "mg" (for media gateway), like this:
mg@mygateway.whatever.net
defining an endpoint like this doesn't change any of the protocol semantics. the "mg" endpoint and other endpoints (like digital trunks) in the gateway are still independent endpoints and MUST be treated as such ๐ for example, RestartInProgress commands MUST still be issued for all endpoints in the gateway as usual.
E.5 Range Wildcards
as Section 2.1.2 describes, the MGCP endpoint naming scheme defines the "all of" and "any of" wildcards for the individual terms in a local endpoint name ๐ธ the "all of" wildcard is super useful for cutting down on the number of messages, but by definition it can only be used when you want to refer to all instances of a given term in the local endpoint name. also, when the gateway is sending a command to the Call Agent, the "all of" wildcard can only be used if all of the endpoints it names have the same "notified entity". implementations that want a finer-grained wildcarding scheme can use the range wildcarding scheme described here ๐ฏ
a range wildcard is defined like this:
RangeWildcard = "[" NumericalRange *( "," NumericalRange ) "]"
NumericalRange = 1*(DIGIT) [ "-" 1*(DIGIT) ]
white space is not permitted ๐ also, since range wildcards use the character "[" to mark the start of a range, the "[" character MUST NOT be used in endpoint names that use range wildcards. the length of a range wildcard SHOULD be kept to a reasonably small value, e.g., 128 characters ๐
range wildcards can be used anywhere an "all of" wildcard can be used, and the semantics are identical for the endpoints named. however, it MUST be noted that using the range wildcarding scheme requires support on both the gateway and the Call Agent ๐ซถ so a gateway MUST NOT assume that its Call Agent supports range wildcarding, and vice versa. in practice, this usually means both the gateway and the Call Agent need to be provisioned consistently to use range wildcards ๐ง also, if a gateway or Call Agent using range wildcards gets an error response that could point to a possible endpoint naming problem, they MUST be able to automatically revert to not using range wildcards ๐
the following examples illustrate the use of range wildcards:
ds/ds1-1/[1-12]
ds/ds1-1/[1,3,20-24]
ds/ds1-[1-2]/*
ds/ds3-1/[1-96]
the following example illustrates how to use one in a command:
RSIP 1204 ds/ds3-1/[1-96]@tgw-18.whatever.net MGCP 1.0
RM: restart
RD: 0
Appendix F: Example Command Encodings ๐
this appendix gives examples of commands and responses shown with the actual encoding used ๐ there's an example for each command. all commentary shown in the commands and responses is optional ๐ง
F.1 NotificationRequest โจ
okay bestie, the first one is a NotificationRequest that rings a phone and waits for someone to pick up the receiver ๐ it's giving simple and iconic ๐
RQNT 1201 aaln/1@rgw-2567.whatever.net MGCP 1.0
N: ca@ca1.whatever.net:5678
X: 0123456789AC
R: l/hd(N)
S: l/rg
and the gateway replies with a big yay, it worked ๐
200 1201 OK
the second one is way more main character ๐ it waits for an off-hook event, then plays dial-tone and collects digits according to the digit map. the notified entity is set to ca@ca1.whatever.net:5678. since the SignalRequests parameter is empty (it could've been left out totally), every TO signal that's currently active gets stopped ๐ all the events in the quarantine buffer get processed too, and the events to detect in the notification state include fax tones ๐ on top of the requested events and the persistent ones. ngl so much is happening ๐ญ
RQNT 1202 aaln/1@rgw-2567.whatever.net MGCP 1.0
N: ca@ca1.whatever.net:5678
X: 0123456789AC
R: L/hd(A, E(S(L/dl),R(L/oc, L/hu, D/[0-9#*T](D))))
D: (0T|00T|#xxxxxxx|*xx|91xxxxxxxxxx|9011x.T)
S:
Q: process
T: G/ft
and the response says it went through โจ
200 1202 OK
F.2 Notify
this one is the gateway telling the Call Agent that an off-hook happened, followed by a 12-digit number that starts with "91" ๐ฒ it carries a transaction identifier so it can be matched up with the NotificationRequest it came from ๐ the command goes to whoever the current "notified entity" is. that's usually the actual value from the NotifiedEntity parameter, which here is ca@ca1.whatever.net:5678, but a failover situation could have swapped it out ๐
NTFY 2002 aaln/1@rgw-2567.whatever.net MGCP 1.0
N: ca@ca1.whatever.net:5678
X: 0123456789AC
O: L/hd,D/9,D/1,D/2,D/0,D/1,D/8,D/2,D/9,D/4,D/2,D/6,D/6
the Notify response is a success ๐ฅณ
200 2002 OK
F.3 CreateConnection
the first CreateConnection makes a brand new connection that belongs to the specified CallId ๐ง the LocalConnectionOptions pick G.711 mu-law as the codec with a 10 ms packetization period, and the connection mode is "receive only" ๐
CRCX 1204 aaln/1@rgw-2567.whatever.net MGCP 1.0
C: A3C47F21456789F0
L: p:10, a:PCMU
M: recvonly
it worked, so the response comes back with a connection identifier for the new connection ๐ the session description rides along too. there's an empty line sitting right before it, so keep your eyes peeled ๐
200 1204 OK
I: FDE234C8
v=0
o=- 25678 753849 IN IP4 128.96.41.1
s=-
c=IN IP4 128.96.41.1
t=0 0
m=audio 3456 RTP/AVP 0
the second one is a CreateConnection that also carries a notification request and a RemoteConnectionDescriptor ๐
CRCX 1205 aaln/1@rgw-2569.whatever.net MGCP 1.0
C: A3C47F21456789F0
L: p:10, a:PCMU
M: sendrecv
X: 0123456789AD
R: L/hd
S: L/rg
v=0
o=- 25678 753849 IN IP4 128.96.41.1
s=-
c=IN IP4 128.96.41.1
t=0 0
m=audio 3456 RTP/AVP 0
this one fails ๐ the phone was already off-hook, so there's no connection-id and no session description coming back, just the error
401 1205 Phone off-hook
the third example is where the provisional response and the three-way handshake show up ๐ค we create another connection and ack the previous response using the response acknowledgement parameter K
CRCX 1206 aaln/1@rgw-2569.whatever.net MGCP 1.0
K: 1205
C: A3C47F21456789F0
L: p:10, a:PCMU
M: inactive
v=0
o=- 25678 753849 IN IP4 128.96.41.1
s=-
c=IN IP4 128.96.41.1
t=0 0
m=audio 3456 RTP/AVP 0
first comes a provisional response, which is basically "hold on, I'm working on it" โณ
100 1206 Pending
I: DFE233D1
v=0
o=- 4723891 7428910 IN IP4 128.96.63.25
s=-
c=IN IP4 128.96.63.25
t=0 0
m=audio 3456 RTP/AVP 0
then a little later, the final response shows up ๐
200 1206 OK
K:
I: DFE233D1
v=0
o=- 4723891 7428910 IN IP4 128.96.63.25
s=-
c=IN IP4 128.96.63.25
t=0 0
m=audio 3456 RTP/AVP 0
the Call Agent acks that final response, as requested ๐
000 1206
and just like that the transaction is complete ๐ซถ
F.4 ModifyConnection
the first ModifyConnection just flips the connection mode to "send/receive" โ๏ธ the notified entity gets set at the same time
MDCX 1209 aaln/1@rgw-2567.whatever.net MGCP 1.0
C: A3C47F21456789F0
I: FDE234C8
N: ca@ca1.whatever.net
M: sendrecv
success, obviously ๐
200 1209 OK
the second one passes in a session description and adds a notification request, so the endpoint starts playing ring-back tones to the user ๐ very cute, very effective
MDCX 1210 aaln/1@rgw-2567.whatever.net MGCP 1.0
C: A3C47F21456789F0
I: FDE234C8
M: recvonly
X: 0123456789AE
R: L/hu
S: G/rt
v=0
o=- 4723891 7428910 IN IP4 128.96.63.25
s=-
c=IN IP4 128.96.63.25
t=0 0
m=audio 3456 RTP/AVP 0
and the response says it worked โจ (the original example shows this one replying as 200 1206 OK, so that's what's happening here too ๐)
200 1206 OK
F.5 DeleteConnection (from the Call Agent)
in this one the Call Agent just tells the gateway to delete the connection "FDE234C8" on the endpoint ๐๏ธ bye bye
DLCX 1210 aaln/1@rgw-2567.whatever.net MGCP 1.0
C: A3C47F21456789F0
I: FDE234C8
the response is a success, and since the connection got deleted, the connection parameters come back with it ๐
250 1210 OK
P: PS=1245, OS=62345, PR=780, OR=45123, PL=10, JI=27, LA=48
F.6 DeleteConnection (from the gateway)
now the gateway is the one sending DeleteConnection to the Call Agent ๐ค to let it know a connection on the endpoint has been deleted. the ReasonCode explains why, and the Connection Parameters are included too ๐งพ
DLCX 1210 aaln/1@rgw-2567.whatever.net MGCP 1.0
C: A3C47F21456789F0
I: FDE234C8
E: 900 - Hardware error
P: PS=1245, OS=62345, PR=780, OR=45123, PL=10, JI=27, LA=48
the Call Agent sends back a success response ๐ซถ
200 1210 OK
F.7 DeleteConnection (multiple connections from the Call Agent)
in the first example, the Call Agent asks the gateway to delete every connection tied to call "A3C47F21456789F0" on that endpoint ๐งน so tidy
DLCX 1210 aaln/1@rgw-2567.whatever.net MGCP 1.0
C: A3C47F21456789F0
and the response says the connection(s) were deleted โ
250 1210 OK
the second example goes even bigger ๐ณ the Call Agent wants every connection related to all of the endpoints specified gone, so it uses the wildcard in the local part of the endpoint name
DLCX 1210 aaln/*@rgw-2567.whatever.net MGCP 1.0
and that's a success too ๐
250 1210 OK
F.8 AuditEndpoint
in the first example the Call Agent wants to know what endpoints live on the gateway, so it uses the "all of" wildcard for the local part of the endpoint name ๐
AUEP 1200 *@rgw-2567.whatever.net MGCP 1.0
the gateway says yes and hands over a list of endpoint names ๐
200 1200 OK
Z: aaln/1@rgw-2567.whatever.net
Z: aaln/2@rgw-2567.whatever.net
the second example asks for the capabilities of one specific endpoint ๐ง
AUEP 1201 aaln/1@rgw-2567.whatever.net MGCP 1.0
F: A
the response comes back with the capabilities too. two codecs are supported, but they don't have the same capabilities, so you get two separate capability sets back ๐ถ
200 1201 OK
A: a:PCMU, p:10-100, e:on, s:off, v:L;S, m:sendonly;
recvonly;sendrecv;inactive;netwloop;netwtest
A: a:G729, p:30-90, e:on, s:on, v:L;S, m:sendonly;
recvonly;sendrecv;inactive;confrnce;netwloop
the line breaks inside the Capabilities lines are only there so they fit on the page ๐ they are not allowed in a real implementation, so don't copy them over like that!
the third example is the Call Agent auditing a bunch of different info for the endpoint at once ๐๏ธ
AUEP 2002 aaln/1@rgw-2567.whatever.net MGCP 1.0
F: R,D,S,X,N,I,T,O,ES
and the response is a success with all of it
200 2002 OK
R: L/hu,L/oc(N),D/[0-9](N)
D:
S: L/vmwi(+)
X: 0123456789B1
N: [128.96.41.12]
I: 32F345E2
T: G/ft
O: L/hd,D/9,D/1,D/2
ES: L/hd
so the list of requested events has three events in it ๐ when no package name is given, the default package is assumed. the same goes for actions, so the default action (Notify) must therefore be assumed for the "L/hu" event ๐ the empty digit map value means the endpoint doesn't have a digit map right now ๐ there aren't any active time-out signals, but the OO signal "vmwi" is on, so it's included. it was parameterized here, though the parameter could've been left out too โจ the current notified entity is an IP address, and there's only one connection on the endpoint. DetectEvents is currently "G/ft", and the ObservedEvents list has the four events that were specified ๐ finally, the event-states audit shows the phone was off-hook when the transaction got processed ๐
F.9 AuditConnection
the first example is an AuditConnection where we check the CallId, NotifiedEntity, LocalConnectionOptions, Connection Mode, LocalConnectionDescriptor, and the Connection Parameters ๐
AUCX 2003 aaln/1@rgw-2567.whatever.net MGCP 1.0
I: 32F345E2
F: C,N,L,M,LC,P
the response is a success and includes the info for everything that was requested ๐
200 2003 OK
C: A3C47F21456789F0
N: ca@ca1.whatever.net
L: p:10, a:PCMU
M: sendrecv
P: PS=395, OS=22850, PR=615, OR=30937, PL=7, JI=26, LA=47
v=0
o=- 4723891 7428910 IN IP4 128.96.63.25
s=-
c=IN IP4 128.96.63.25
t=0 0
m=audio 1296 RTP/AVP 0
in the second example we ask to audit the RemoteConnectionDescriptor and the LocalConnectionDescriptor ๐ซ
AUCX 1203 aaln/2@rgw-2567.whatever.net MGCP 1.0
I: FDE234C8
F: RC,LC
the response is a success with the requested info. this time there's no RemoteConnectionDescriptor, so the RemoteConnectionDescriptor only gets the protocol version field ๐ฅบ
200 1203 OK
v=0
o=- 4723891 7428910 IN IP4 128.96.63.25
s=-
c=IN IP4 128.96.63.25
t=0 0
m=audio 1296 RTP/AVP 0
v=0
F.10 RestartInProgress โจ
Okay so the first example is a RestartInProgress message from a gateway, telling the Call Agent that the endpoint is going out-of-service in 300 seconds ๐ญ๐ฅ
RSIP 1200 aaln/1@rgw-2567.whatever.net MGCP 1.0
RM: graceful
RD: 300
The Call Agent replies that the transaction went through ๐
200 1200 OK
In the second example, the gateway tells the Call Agent that all of its endpoints are being placed in-service in 0 seconds, which means they're already in service ๐ธ The restart delay could have been left out too.
RSIP 1204 *@rgw-2567.whatever.net MGCP 1.0
RM: restart
RD: 0
The Call Agent says success, and it also gives the endpoints a brand new "notified entity" ๐ฆ
200 1204 OK
N: CA-1@whatever.net
Plot twist: the command could have failed instead, and it still comes with a new "notified entity" ๐
521 1204 OK
N: CA-1@whatever.net
In that case, the command has to be retried so the "restart procedure" can be satisfied, and this time it goes to Call Agent "CA-1@whatever.net" ๐ง
Appendix G: Example Call Flows ๐
The message flow tables in this section use the following abbreviations:
rgw= Residential Gatewayca= Call Agentn+= step 'n' is repeated one or more times
Note that any use of upper and lower case within the text of the messages is to aid readability and is not in any way a requirement. The only requirement involving case is to be case insensitive at all times. ๐
G.1 Restart ๐
G.1.1 Residential Gateway Restart
Here's a message sequence that might happen when a call agent (ca) gets contacted by two independent residential gateways (rgw1 and rgw2) that have restarted. Bestie, this is giving reboot drama ๐
---------------------------------------------------------------------
|step#| usr1 | rgw1 | ca | rgw2 | usr2 |
|=====|============|============|============|============|===========|
| 1 | | rsip -> | | | |
| | | | <- ack | | |
|-----|------------|------------|------------|------------|-----------|
| 2 | | | <- auep | | |
| | | ack -> | | | |
|-----|------------|------------|------------|------------|-----------|
| 3+ | | | <- rqnt | | |
| | | ack -> | | | |
|-----|------------|------------|------------|------------|-----------|
| 4 | | | | <- rsip | |
| | | | ack -> | | |
|-----|------------|------------|------------|------------|-----------|
| 5 | | | auep -> | | |
| | | | | <- ack | |
|-----|------------|------------|------------|------------|-----------|
| 6+ | | | rqnt -> | | |
| | | | | <- ack | |
---------------------------------------------------------------------
Step 1 - RestartInProgress (rsip) from rgw1 to ca
rgw1 uses DNS to find the domain name of ca and sends to the default port of 2727. The command looks like this:
rsip 1 *@rgw1.whatever.net mgcp 1.0
rm: restart
The * tells ca that all endpoints of rgw1 are restarting, and "restart" is the restart method. The Call Agent ca acks the command with an acknowledgement message that has the transaction-id (here, 1) for the command. It sends the ack back to rgw1 using the same port that was the source port for the rsip. If none was indicated, it uses the default port of 2727.
200 1 ok
A response code is mandatory. In this case, 200 means "the requested transaction was executed normally". The response string is optional, so here "ok" is just an extra description โจ
Step 2 - AuditEndpoint (auep) from ca to rgw1
The command looks like this:
auep 153 *@rgw1.whatever.net mgcp 1.0
The * asks rgw1 for audit info on all of its endpoints. rgw1 acks the command with the transaction-id (here, 153), and it includes a list of its endpoints. In this example, rgw1 has two endpoints, aaln/1 and aaln/2.
200 153 ok
Z: aaln/1@rgw1.whatever.net
Z: aaln/2@rgw1.whatever.net
Once ca has the endpoint ids, it may send individual AuditEndpoint commands where the * is swapped for the id of a given endpoint. In response, rgw1 would replace the endpoint id list from the example with the info requested for that endpoint. This optional message exchange isn't shown in this example ๐
Step 3 - NotificationRequest (rqnt) from ca to each endpoint of rgw1
Here ca sends two rqnts, one for aaln/1:
rqnt 154 aaln/1@rgw1.whatever.net mgcp 1.0
r: l/hd(n)
x: 3456789a0
and a second one for aaln/2:
rqnt 155 aaln/2@rgw1.whatever.net mgcp 1.0
r: l/hd(n)
x: 3456789a1
Note that in the requested events parameter line, the event is fully specified as "l/hd", i.e., with the package name, so there's no potential ambiguity. This is the recommended behavior ๐ง For clarity, the action (which here is to Notify) is spelled out with the "(n)". If no action is specified, Notify is assumed as the default regardless of the event. If any other action is desired, it must be stated explicitly.
The response from rgw1 to these requests is an acknowledgement from aaln/1:
200 154 ok
and from aaln/2:
200 155 ok
Step 4 RestartInProgress (rsip) from rgw2 to ca
rsip 0 *@rgw2.whatever.net mgcp 1.0
rm: restart
followed by the acknowledgement from ca:
200 0 ok
Step 5 - AuditEndpoint (auep) from ca to rgw2
auep 156 *@rgw2.whatever.net mgcp 1.0
followed by an acknowledgement from rgw2:
200 156 ok
z: aaln/1@rgw2.whatever.net
z: aaln/2@rgw2.whatever.net
Step 6 - NotificationRequest (rqnt) from ca to each endpoint of rgw2
rqnt 157 aaln/1@rgw2.whatever.net mgcp 1.0
r: l/hd(n)
x: 3456789a2
followed by:
rqnt 158 aaln/2@rgw2.whatever.net mgcp 1.0
r: l/hd(n)
x: 3456789a3
with rgw2 acking for aaln/1:
200 157 ok
and for aaln/2:
200 158 ok
G.1.2 Call Agent Restart
This table shows the message sequence that happens when a call agent (ca) restarts. How it figures out the address info of the gateways (here rgw1 and rgw2) isn't covered in this document. For interoperability, it is RECOMMENDED to provide the ability to configure the call agent to send AUEP (*) to specific addresses and ports ๐ซถ
---------------------------------------------------------------------
| # | usr1 | rgw1 | ca | rgw2 | usr2 |
|===|=============|============|============|============|============|
| 1 | | | <- auep | | |
| | | ack -> | | | |
|---|-------------|------------|------------|------------|------------|
| 2+| | | <- rqnt | | |
| | | ack -> | | | |
|---|-------------|------------|------------|------------|------------|
| 3 | | | auep -> | | |
| | | | | <- ack | |
|---|-------------|------------|------------|------------|------------|
| 4+| | | rqnt -> | | |
| | | | | <- ack | |
---------------------------------------------------------------------
Step 1 - AuditEndpoint (auep) from ca to rgw1
The command looks like this:
auep 0 *@rgw1.whatever.net mgcp 1.0
The * asks rgw1 for audit info on all of its endpoints. rgw1 acks the command with the transaction id (here, 0), and it includes a list of its endpoints. In this example, rgw1 has two endpoints, aaln/1 and aaln/2.
200 0 ok
z: aaln/1@rgw1.whatever.net
z: aaln/2@rgw1.whatever.net
Once ca has the endpoint ids, it may send individual AuditEndpoint commands where the * is swapped for the id of a given endpoint. In response, rgw1 would replace the endpoint id list from the example with the info requested for that endpoint. This optional message exchange isn't shown in this example โจ
Step 2 - NotificationRequest (rqnt) off-hook from ca to rgw1
Here ca sends two rqnts, one for aaln/1:
rqnt 1 aaln/1@rgw1.whatever.net mgcp 1.0
r: l/hd(n)
x: 234567890
and a second one for aaln/2:
rqnt 2 aaln/2@rgw1.whatever.net mgcp 1.0
r: l/hd(n)
x: 234567891
The response from rgw1 to these requests is an acknowledgement from aaln/1:
200 1 ok
and from aaln/2:
200 2 ok
Step 3 - AuditEndpoint (auep) from ca to rgw2
auep 3 *@rgw2.whatever.net mgcp 1.0
followed by an acknowledgement from rgw2:
200 3 ok
z: aaln/1@rgw2.whatever.net
z: aaln/2@rgw2.whatever.net
Step 4 - NotificationRequest (rqnt) from ca to each endpoint of rgw2
rqnt 4 aaln/1@rgw2.whatever.net mgcp 1.0
r: l/hd(n)
x: 234567892
followed by:
rqnt 5 aaln/2@rgw2.whatever.net mgcp 1.0
r: l/hd(n)
x: 234567893
with rgw2 acking for aaln/1:
200 4 ok
and for aaln/2:
200 5 ok
G.2 Connection Creation ๐ฆ
G.2.1 Residential Gateway to Residential Gateway
This table shows the message sequence that happens when a user (usr1) makes a call through a residential gateway (rgw1) to a user served by another residential gateway (rgw2). It only shows the communication between the residential gateways and the call agent (ca). The local name of the endpoints here is aaln/1 for both gateways, and any references in the step descriptions to rgw1 and rgw2 can be read as aaln/1 of rgw1 and aaln/1 of rgw2. Note that this is only an example and is not the only legal call scenario ๐
Table F.3: Residential Gateway Connection Creation
---------------------------------------------------------------------
| # | usr1 | rgw1 | ca | rgw2 | usr2 |
|===|=============|============|============|============|============|
| 1 | offhook -> | ntfy -> | | | |
| | | | <- ack | | |
|---|-------------|------------|------------|------------|------------|
| 2 | <- dialtone | | <- rqnt | | |
| | | ack -> | | | |
|---|-------------|------------|------------|------------|------------|
| 3 | digits -> | ntfy -> | | | |
| | | | <- ack | | |
|---|-------------|------------|------------|------------|------------|
| 4 | | | <- rqnt | | |
| | | ack -> | | | |
|---|-------------|------------|------------|------------|------------|
| 5 | <- recvonly | | <- crcx | | |
| | | ack -> | | | |
|---|-------------|------------|------------|------------|------------|
| 6 | | | crcx -> | | sendrcv -> |
| | | | | <- ack | |
|---|-------------|------------|------------|------------|------------|
| 7 | <- recvonly | | <- mdcx | | |
| | | ack -> | | | |
|---|-------------|------------|------------|------------|------------|
| 8 | <- ringback | | <- rqnt | | |
| | | ack -> | | | |
|---|-------------|------------|------------|------------|------------|
| 9 | | | rqnt -> | | ringing -> |
| | | | | <- ack | |
|---|-------------|------------|------------|------------|------------|
|10 | | | | <- ntfy | <- offhook |
| | | | ack -> | | |
|---|-------------|------------|------------|------------|------------|
|11 | | | rqnt -> | | |
| | | | | <- ack | |
|---|-------------|------------|------------|------------|------------|
|12 | | | <- rqnt | | |
| | | ack -> | | | |
|---|-------------|------------|------------|------------|------------|
|13 | <- sendrcv | | <- mdcx | | |
| | | ack -> | | | |
---------------------------------------------------------------------
Step 1 - Notify (ntfy) offhook from rgw1 to ca ๐
This ntfy is the result of usr1 going offhook ๐, and it assumes ca had already sent an rqnt with RequestId "445678944" to rgw1, asking for a heads-up if an offhook happens. โจ
ntfy 12 aaln/1@rgw1.whatever.net mgcp 1.0
o: l/hd
x: 445678944
Acknowledgement from ca:
200 12 ok
Step 2 - Request Notification (rqnt) for digits from ca to rgw1 ๐
ca asks rgw1 to notify it if the phone goes back on-hook ๐ด, to collect digits according to the digit map, and to provide dialtone ๐ถ.
rqnt 1057 aaln/1@rgw1.whatever.net mgcp 1.0
r: l/hu(n), d/[0-9#*T](d)
s: l/dl
x: 445678945
d: 5xxx
Acknowledgement from rgw1:
200 1057 ok
Step 3 - Notify (ntfy) digits from rgw1 to ca ๐ข
ntfy 13 aaln/1@rgw1.whatever.net mgcp 1.0
o: d/5, d/0, d/0, d/1
x: 445678945
Acknowledgement from ca:
200 13 ok
Step 4 - Request Notification (rqnt) from ca to rgw1 ๐ฆ
ca asks rgw1 to notify it in the event of an on-hook transition. ๐ด
rqnt 1058 aaln/1@rgw1.whatever.net mgcp 1.0
r: l/hu(n)
x: 445678946
Acknowledgement from rgw1:
200 1058 ok
Step 5 - Create Connection (crcx) from ca to rgw1 ๐ธ
ca requests a brand new connection on rgw1 ๐ง, with the local connection options: 20 msec as the packetization period, G.711 mu-law as the codec, and receive only as the mode. It's giving very specific, very intentional energy ๐ .
crcx 1059 aaln/1@rgw1.whatever.net mgcp 1.0
c: 9876543210abcdef
l: p:20, a:PCMU
m: recvonly
rgw1 acknowledges that the new connection, "456789fedcba5", has been created ๐. A blank line comes next, followed by the SDP parameters:
200 1059 ok
i: 456789fedcba5
v=0
o=- 23456789 98765432 IN IP4 192.168.5.7
s=-
c=IN IP4 192.168.5.7
t=0 0
m=audio 6058 RTP/AVP 0
Step 6 - Create Connection (crcx) from ca to rgw2 ๐ซถ
ca requests a new connection on rgw2. The request carries the session description that rgw1 handed back, so a two way connection can get started ๐ฅ.
crcx 2052 aaln/1@rgw2.whatever.net mgcp 1.0
c: 9876543210abcdef
l: p:20, a:PCMU
m: sendrecv
v=0
o=- 23456789 98765432 IN IP4 192.168.5.7
s=-
c=IN IP4 192.168.5.7
t=0 0
m=audio 6058 RTP/AVP 0
rgw2 acknowledges that the new connection, "67890af54c9", has been created ๐. Then there's a blank line, followed by the SDP parameters:
200 2052 ok
i: 67890af54c9
v=0
o=- 23456889 98865432 IN IP4 192.168.5.8
s=-
c=IN IP4 192.168.5.8
t=0 0
m=audio 6166 RTP/AVP 0
Step 7 - Modify Connection (mdcx) from ca to rgw1 โจ
ca asks rgw1 to modify the existing connection, "456789fedcba5", so it uses the session description rgw2 returned. This sets up a half duplex connection. It isn't used in this example, but it could be used to give usr1 in band ringback tone, announcements, and so on ๐ต.
mdcx 1060 aaln/1@rgw1.whatever.net mgcp 1.0
c: 9876543210abcdef
i: 456789fedcba5
l: p:20, a:PCMU
M: recvonly
v=0
o=- 23456889 98865432 IN IP4 192.168.5.8
s=-
c=IN IP4 192.168.5.8
t=0 0
m=audio 6166 RTP/AVP 0
Acknowledgement from rgw1:
200 1060 ok
Step 8 - Request Notification (rqnt) from ca for rgw1 to provide ringback ๐
ca asks rgw1 to notify it in the event of an on-hook transition, and also to provide ringback tone ๐.
rqnt 1061 aaln/1@rgw1.whatever.net mgcp 1.0
r: l/hu(n)
s: g/rt
x: 445678947
Acknowledgement from rgw1:
200 1061 ok
Step 9 - Request Notification (rqnt) from ca to rgw2 to provide ringing ๐๏ธ
ca asks rgw2 to keep watching for offhook and to provide ringing ๐ณ.
rqnt 2053 aaln/1@rgw2.whatever.net mgcp 1.0
r: l/hd(n)
s: l/rg
x: 445678948
Acknowledgement from rgw2:
200 2053 ok
Step 10 - Notify (ntfy) offhook from rgw2 to ca ๐
ntfy 27 aaln/1@rgw2.whatever.net mgcp 1.0
o: l/hd
x: 445678948
Acknowledgement from ca:
200 27 ok
Step 11 - Request Notification (rqnt) of on-hook from ca to rgw2 ๐
rqnt 2054 aaln/1@rgw2.whatever.net mgcp 1.0
r: l/hu(n)
x: 445678949
Acknowledgement from rgw2:
200 2054 ok
Step 12 - Request Notification (rqnt) of on-hook from ca to rgw1 ๐
rqnt 1062 aaln/1@rgw1.whatever.net mgcp 1.0
r: l/hu(n)
x: 445678950
Acknowledgement from rgw1:
200 1062 ok
Step 13 - Modify Connection (mdcx) from ca to rgw1 ๐ฅณ
ca asks rgw1 to modify the existing connection, "456789fedcba5", to sendrecv, so a full duplex connection gets initiated ๐ฆ.
mdcx 1063 aaln/1@rgw1.whatever.net mgcp 1.0
c: 9876543210abcdef
i: 456789fedcba5
m: sendrecv
Acknowledgement from rgw1:
200 1063 ok
G.3 Connection Deletion
G.3.1 Residential Gateway to Residential Gateway
Okay so this one shows what happens when usr2 wants to delete an existing connection on rgw2 ๐ฅบ, while the person on the other end is served by a different residential gateway, rgw1. ๐ The table only shows what goes on between the residential gateways and the call agent (ca), so usr1 and usr2 are just there for the vibes. โจ Both gateways use aaln/1 as the local name of their endpoints. Whenever the steps mention rgw1 and rgw2, you can assume they mean aaln/1 on rgw1 and aaln/1 on rgw2 ๐ท.
Table F.4: Residential Gateway Connection Deletion
---------------------------------------------------------------------
| # | usr1 | rgw1 | ca | rgw2 | usr2 |
|===|=============|============|============|============|============|
| 1 | | | | <- ntfy | <- on-hook |
| | | | ack -> | | |
|---|-------------|------------|------------|------------|------------|
| 2 | | | dlcx -> | | |
| | | | | <- ack | |
|---|-------------|------------|------------|------------|------------|
| 3 | | | <- dlcx | | |
| | | ack -> | | | |
|---|-------------|------------|------------|------------|------------|
| 4 | | | rqnt -> | | |
| | | | | <- ack | |
|---|-------------|------------|------------|------------|------------|
| 5 | on-hook -> | ntfy -> | | | |
| | | | <- ack | | |
|---|-------------|------------|------------|------------|------------|
| 6 | | | <- rqnt | | |
| | | ack -> | | | |
---------------------------------------------------------------------
Step 1 - Notify (ntfy) offhook from rgw1 to ca ๐ธ
This ntfy is what happens when usr2 goes on-hook ๐ด. It assumes ca had already sent rgw2 an rqnt asking for a ping when an on-hook happens (you'll find that in the end of the Connection Creation sequence ๐).
ntfy 28 aaln/1@rgw2.whatever.net mgcp 1.0
o: l/hu
x: 445678949
Acknowledgement from ca:
200 28 ok
Step 2 - Delete Connection (dlcx) from ca to rgw2 ๐๏ธ
ca asks rgw2 to delete the connection "67890af54c9" ๐.
dlcx 2055 aaln/1@rgw1.whatever.net mgcp 1.0
c: 9876543210abcdef
i: 67890af54c9
Acknowledgement from rgw2. Heads up, the response code is "250", and that means "the connection was deleted" ๐.
250 2055 ok
Step 3 - Delete Connection (dlcx) from ca to rgw1 ๐งน
ca asks rgw1 to delete the connection "456789fedcba5" ๐ท.
dlcx 1064 aaln/1@rgw1.whatever.net mgcp 1.0
c: 9876543210abcdef
i: 456789fedcba5
Acknowledgement from rgw1:
250 1064 ok
Step 4 - NotificationRequest (rqnt) from ca to rgw2 ๐ฆ
ca asks rgw2 to notify it in the event of an offhook transition ๐.
rqnt 2056 aaln/1@rgw2.whatever.net mgcp 1.0
r: l/hd(n)
x: 445678951
Acknowledgement from rgw2:
200 2056 ok
Step 5 - Notify (ntfy) on-hook from rgw1 to ca ๐ด
rgw1 lets ca know that usr1 went back on-hook ๐ซถ.
ntfy 15 aaln/1@rgw1.whatever.net mgcp 1.0
o: l/hu
x: 445678950
Acknowledgement from ca:
200 15 ok
Step 6 - NotificationRequest (rqnt) offhook from ca to rgw1 ๐
ca asks rgw1 to notify it in the event of an offhook transition. ๐โจ
rqnt 1065 aaln/1@rgw1.whatever.net mgcp 1.0
r: l/hd(n)
x: 445678952
Acknowledgement from rgw1:
200 1065 ok
Authors' Addresses ๐
Flemming Andreasen
Cisco Systems
499 Thornall Street, 8th Floor
Edison, NJ 08837
EMail: fandreas@cisco.com
Bill Foster
Cisco Systems
771 Alder Drive
Milpitas, CA 95035
EMail: bfoster@cisco.com
Full Copyright Statement โจ
Okay bestie, the legal part ๐ It's short, I promise ๐ซถ
Copyright (C) The Internet Society (2003). All Rights Reserved. ๐
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. โจ However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English. ๐
The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns. ๐
This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS 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. ๐
Acknowledgement ๐ธ
Funding for the RFC Editor function is currently provided by the Internet Society. ๐ซถ
๐ฆ where this page comes from
- ietf: rfc3435 2003-01
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms