Header Manipulation Rules for SDP

The Oracle Enterprise Communications Broker supports SIP header and parameter manipulation rules for four types of SIP message contents:

  • headers
  • elements within headers
  • ASCII-encoded Multipurpose Internet Mail Extensions (MIME) bodies
  • binary-encoded MIME ISDN User Part (ISUP) bodies

While Session Description Protocol (SDP) offers and answers can be manipulated in a fashion similar to ASCII-encoded MIME, such manipulation is primitive in that it lacks the ability to operate at the SDP session- and media-levels.

In addition, the system supports a variant of Header Manipulation Rules (HMR) operating on ASCII-encoded SDP bodies, with specific element types for descriptors at both the session-level and media-level, and the ability to apply similar logic to SDP message parts as is done for SIP header elements.

The configuration object, mime-sdp-rules, under sip-manipulation specifically addresses the manipulation of SDP parts in SIP messages. Just as existing header-rules are used to manipulate specific headers of a SIP message, mime-sdp-rules will be used to manipulate the SDP specific mime-attachment of a SIP message.

SDP Manipulation

mime-sdp-rules function in a similar fashion as header-rules. They provide

  • parameters used to match against specific SIP methods and/or message types
  • parameters used to match and manipulate all or specified parts of an SDP offer or answer
  • a means of comparing search strings or expressions against the entire SDP
  • different action types to allow varying forms of manipulation

Since only a single SDP can exist within a SIP message, users need not specify a content-type parameter as is necessary for a mime-rule. A mime-sdp-rule operates on the single SDP within the SIP message. If no SDP exists with the message, one can be added. If the message already contains a mime attachment, adding SDP results in a multipart message.

All manipulations performed against all or parts of the SDP are treated as UTF-8 ASCII encoded text. At the parent-level (mime-sdp-rule) the match-value and new-value parameters execute against the entire SDP as a single string.

An add action only succeeds in the absence of SDP because a message is allowed only a single SDP offer or answer. A delete operation at the mime-sdp-rule level will remove the SDP entirely.

Note that on an inbound sip-manipulation, SDP manipulations interact with the Oracle Enterprise Communications Broker codec-policy. SDP manipulations also interact with codec reordering and media setup. It is very possible to make changes to the SDP such that the call can not be setup due to invalid media parameters, or settings that will affect the ability to transcode the call. Consequently, user manipulation of the SDP can prove risky, and should be approached with appropriate caution.

Three configuration-objects, sdp-session-rule, sdp-media-rule, and mime-header-rule, exist under the mime-sdp-rule. These objects provide finer grained control of manipulating parts of the SDP.

sdp-session-rule

An sdp-session-rule groups all SDP descriptors, up until the first media line, into a single entity, thus allowing the user to perform manipulation operations on a session-specific portion of the SDP.

Like the mime-sdp-rule, all match-value and new-value operations performed at this level are executed against the entire session group as a complete string. Given the sample SDP below, if an sdp-session-rule is configured, the match-value and new-values operate only on the designated portion.

        v=0
        o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4
        s=SDP Seminar
        i=A Seminar on the session description protocol
        u=http://www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.ps
        e=mjh@isi.edu (Mark Handley)
        c=IN IP4 224.2.17.12/127
        t=2873397496 2873404696
        a=recvonly
        m=audio 49170 RTP/AVP 0
        m=video 51372 RTP/AVP 31
        m=application 32416 udp wb
        a=orient:portrait

Nested under the sdp-session-rule configuration object is an sdp-line-rule object, the object that identifies individual descriptors within the SDP. The types of descriptors used at the sdp-session-rule level are v, o, s, i, u, e, p, c, b, t, r, z, k, and a, the descriptors specific to the entire session description.

This level of granularity affords the user a very simple way to making subtle changes to the session portion of the SDP. For instance, it is very common to have to change the connection line at the session level.

The add and delete actions perform no operation at the sdp-session-rule level.

sdp-media-rule

An sdp-media-rule groups all of the descriptors that are associated with a specific media-type into single entity, thus allowing the user to perform manipulation operations on a media-specific portion of the SDP. For example, a user can construct an sdp-media-rule to change an attribute of the audio media type.

Like a mime-sdp-rule, all match-value and new-value operations performed at this level are executed against the entire media-group as a complete string. Given the sample SDP below, if a media-level-descriptor is configured to operate against the application group, the match-value and new-values would operate only on designated portion.

        v=0
        o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4
        s=SDP Seminar
        i=A Seminar on the session description protocol
        u=http://www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.ps
        e=mjh@isi.edu (Mark Handley)
        c=IN IP4 224.2.17.12/127
t=2873397496 2873404696
        a=recvonly
        m=audio 49170 RTP/AVP 0
        m=video 51372 RTP/AVP 31
        m=application 32416 udp wb
        a=orient:portrait

A configuration parameter media-type is used to specify the media group on which to operate. It contains all of the descriptors including the m-line up to the next m-line. This parameter is a string field and must match the media-type exactly as it appears within the SDP. The special media-type media can be used to refer to all media types. This is particularly useful when performing an add operation, when the user wants to add a media section between the first and second medias, but does not know what media type they are. Otherwise, during an add operation, the media section would be added before the specified media-type (if no index parameter was provided).

The types of descriptors used at the sdp-media-rule level are m, i, c, b, k, and a, the descriptors specific to the media description.

This level of granularity affords the user a very simple way to making subtle changes to the media portion of the SDP. For instance, it is very common to have to change the name of an audio format (for example G729 converted to g729b), or to add attributes specific to a certain media-type.

The index operator is supported for the media-type parameter (for example, media-type audio[1]). Like header rules, if no index is supplied, this means operate on all media-types that match the given name. For specifying specific media-types, the non-discrete indices are also supported (for example, ^ - last). Adding a media-type, without any index supplied indicates that the media should be added at the beginning. The special media-type media uses the index as an absolute index to all media sections, while a specific media-type will index relative to that given media type.

For sdp-media-rules set to an action of add where the media-type is set to media, the actual media type is obtained from the new-value, or more specifically, the string after m= and before the first space.

Given the following SDP:

        v=0
        o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4
        c=IN IP4 224.2.17.12/127
        t=2873397496 2873404696
        m=audio 49170 RTP/AVP 0
        m=audio 48324 RTP/AVP 8
        m=video 51372 RTP/AVP 31

With the sdp-media-rule:

sdp-media-rule
        name                       smr
        media-type                 audio[1]
        action                     manipulate
        comparison-type            case-sensitive
        match-value
        new-value                  "m=audio 1234 RTP/AVP 8 16"

This rule operates on the 2nd audio line, changing the port and adding another codec, resulting in the SDP:

        v=0
        o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4
        c=IN IP4 224.2.17.12/127
        t=2873397496 2873404696
        m=audio 49170 RTP/AVP 0
        m=audio 1234 RTP/AVP 8 16
        m=video 51372 RTP/AVP 31

The following rule, however:

sdp-media-rule
        name                       smr
        media-type                 media[1]
        action                     add
        comparison-type            case-sensitive
        match-value
        new-value                  "m=video 1234 RTP/AVP 45"

adds a new video media-type at the 2nd position of all media-lines, resulting in the SDP:

        v=0
        o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4
        c=IN IP4 224.2.17.12/127
        t=2873397496 2873404696
        m=audio 49170 RTP/AVP 0
        m=video 1234 RTP/AVP 45
        m=audio 48324 RTP/AVP 8
        m=video 51372 RTP/AVP 31

sdp-line-rule

Unlike header-rules, sdp descriptors are not added in the order in which they are configured. Instead they are added to the SDP adhering to the grammar defined by RFC 4566 (as is shown below).

      Session description
         v=  (protocol version)
         o=  (originator and session identifier)
         s=  (session name)
         i=* (session information)
         u=* (URI of description)
         e=* (email address)
         p=* (phone number)
            c=* (connection information -- not required if included in
              all media)
         b=* (zero or more bandwidth information lines)
         One or more time descriptions ("t=" and "r=" lines; see
              below)
         z=* (time zone adjustments)
         k=* (encryption key)
         a=* (zero or more session attribute lines)
         Zero or more media descriptions (see below)

      Time description
         t=  (time the session is active)
         r=* (zero or more repeat times)

      Media description, if present
         m=  (media name and transport address)
         i=* (media title)
         c=* (connection information -- optional if included at
              session level)
         b=* (zero or more bandwidth information lines)
         k=* (encryption key)
         a=* (zero or more media attribute lines)

* after the equal sign denotes an optional descriptor.

This hierarchy is enforced meaning that if you configure a rule which adds a session name descriptor followed by a rule which adds a version descriptor, the SDP will be created with the version descriptor first, followed by the session name.

The only validation that will occur is the prevention of adding duplicate values. In much the same way that header-rules prevents the user from adding multiple To headers, the descriptor rule will not allow the user to add multiple descriptors; unless multiple descriptors are allowed, as is in the case of b, t, r and a.

There exists a parameter type under the sdp-line-rule object that allows the user to specify the specific line on which to perform the operation. For example: v, o, s, i, u, e, p, c, b, t, r, z, k, a, and m. Details on these types can be found in RFC 4566.

For those descriptors, of which there may exist zero or more (b, t, r, and a) entries, indexing grammar may be used to reference the specific instance of that attribute. This indexing grammar is consistent with that of header-rules for referring to multiple headers of the same type.

Given the example SDP below:

        v=0
        o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4
        s=SDP Seminar
        i=A Seminar on the session description protocol
        u=http://www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.ps
        e=mjh@isi.edu (Mark Handley)
        c=IN IP4 224.2.17.12/127
        t=2873397496 2873404696
        r=604800 3600 0 90000
        r=7d 1h 0 25h
        a=recvonly
        m=audio 49170 RTP/AVP 0
        m=video 51372 RTP/AVP 31
        m=application 32416 udp wb
        a=orient:portrait

and the following sdp-line-rule:

        sdp-line-rule
           name                 removeRepeatInterval
           type                 r[1]
           action               delete

The rule removeRepeatInterval removes the second repeat interval descriptor within the SDP.

The behavior of all SDP rules follow the same behavior of all manipulation rules in that they are executed in the order in which they are configured and that each rule executes on the resultant of the previous rule.

Each descriptor follows its own grammar and rules depending on the type specified. The values of the descriptor are evaluated at runtime since the new-values themselves are evaluated at runtime. At this time no validation of the grammar for each of the types is performed. The user is responsible for properly formatting each of the descriptors according to their specifications.

For instance, the version (v) descriptor can be removed from the SDP but leaving all descriptors for that SDP, causing the SDP to become invalid. This is consistent with the way header-rules operate, in that there is no validation for the specific headers once they have been manipulated through HMR.

Regular Expression Interpolation

An interpolated regular expression is a regular expression that is compiled and evaluated at runtime. Today all regular expressions are compiled at configuration time in order to improve performance. There are cases where a regular expression is determined dynamically from data within a SIP message. In these circumstances the regular expression is unknown until the time of execution.

In order to have a regular expression be interpolated at runtime, it must be contained within a set of {}. An interpolated expression can have any number of regular expressions and strings appended together. Any characters to the left or right of the curly braces will be appended to the value within the curly braces. The curly braces are effectively two operators treated as one (interpolate the value contained within and then concatenate the values to the left and right of the curly braces). If the comparison-type is set to pattern-rule and the match-value contains a value that matches the grammar below, then it will be treated as an interpolated expression.

([^\\]|^)\{\$[^0-9]+[^}]*\}

The example below demonstrates using a user defined variable within a regular expression of another rule at runtime.

element-rule

        name                           someRule
        type                           header-value
        action                         replace
        comparison-type                pattern-rule
        match-value                    ^sip:{$rule1.$0}@(.+)$
        new-value                      sip:bob@company.com

If the value of $rule1.$0 evaluates to alice then it will successfully match against the string sip:alice@comcast.net. An interpolated expression can be as simple as “{$rule1.$0}” or as complex as ^sip:{rule1.$0}@{$rule2[1].$2}$. It is not possible to interpolate a normal regular expression since the grammar will not allow the user to enter such an expression. Only variables can be contained with the curly braces.

The resultant of interpolated expressions can be stored in user defined variables. Given the same example from above, if the rule someRule was referenced by another rule, the value of sip:alice@comcast.net would be stored within that rule.

Interpolation only makes a single pass at interpolation, but does so every time the Rule executes. In other words, if the Rule is applied to the Route header, it will interpolate again for each Route header instance. What this means is that the value within the curly braces will only be evaluated once. For instance, if the value {$someRule.$1} evaluates to {$foobar.$2} the Oracle Enterprise Communications Broker (OECB) will treat $foobar.$2 as a literal string which it will compile as a regular expression. The OECB will not recursively attempt to evaluate $foobar.$2, even if it was a valid user defined variable.

Interpolated regular expressions will evaluate to TRUE if an only if both the regular expression itself can be compiled and it successfully matches against the compared string.

Regular Expressions as Boolean Expressions

Regular expressions can be used as boolean expressions today if they are the only value being compared against a string, as is shown in the case below.

mime-rule
        name                           someMimeRule
        content-type                   application/text
        action                         replace
        comparison-type                pattern-rule
        match-value                    ^every good boy .*
        new-value                      every good girl does fine
However, regular expressions can not be used in conjunction with other boolean expressions to form more complex boolean expressions, as is shown below.

mime-rule
     name                      someMimeRule
     content-type              application/text
     action                    replace
     comparison-type           boolean
     match-value               $someRule & ^every good boy .*
     new-value                 every good girl does fine

There are many cases where the user has the need to compare some value as a regular expression in conjunction with another stored value. It is possible to perform this behavior today, however it requires an extra step in first storing the value with the regular expression, followed by another Manipulation Rule which compares the two boolean expressions together (e.g. $someRule & $someMimeRule).

In order to simplify the configuration of some sip-manipulations and to make them more efficient this functionality is being added.

Unfortunately, it is not possible to just use the example as is shown above. The problem is there are many characters that are commonly used in regular expressions that would confuse the HMR expression parser (such as $, and +). Therefore delimiting characters need to be used to separate the regular expression from the other parts of the expression.

To treat a regular expression as a boolean expression, it needs to be enclosed within the value $REGEX(<expression>,<compare_string>=$ORIGINAL); where <expression> is the regular expression to be evaluated. <compare_string> is the string to compare against the regular expression. This second argument to the function is defaulted to $ORIGINAL which is the value of the of the specific Manipulation Rule object. It can be overridden to be any other value the user desires.

The proper configuration for the example above to use regular expressions as boolean expressions is

mime-rule
        name             someMimeRule
        content-type     application/text
        action           replace
        comparison-type  boolean
        match-value      $someRule & $REGEX(“^every good boy .*”)
        new-value        every good girl does fine

It is also possible to use expressions as arguments to the $REGEX function. These expressions will in turn be evaluated prior to executing the $REGEX function. A more complex example is illustrated below.

header-rule
        name              checkPAU
        header-name       request-uri
        action            reject
        comparison-type   boolean
        match-value       (!$REGEX($rule1[0],$FROM_USER))&
                          (!$REGEX($rule2[0],$PAI_USER))
        msg-type          request
        new-value         403:Forbidden
        methods           INVITE,SUBSCRIBE,MESSAGE,PUBLISH,
                          OPTIONS, REFER

It should be noted that when using $REGEX() in a boolean expression, the result of that expression is not stored in the user variable. The comparison-type must be set to pattern-rule in order to store the result of a regular expression.

The arguments to the $REGEX() function are interpolated by default. This is the case since the arguments themselves must be evaluated at runtime. The following example is also valid.

mime-rule
        name                someMimeRule
        content-type        application/text
        action              replace
        comparison-type     boolean
        match-value         $someRule & $REGEX(“^every good
                            {$rule1[0].$0} .*”)

Moving Manipulation Rules

You can move rules within any manipulation-rule container. Any manipulation rule that contains sub-rules offers the ACLI command move <from index> <to index>. For example, given the order and list of rules below:

1. rule1

2. rule2

3. rule3

4. rule4

You can move rule3 to position 1 by executing move 3 1. The resulting order is: rule3, rule1, rule2, rule4. A move operation causes a shift (or insert before) for all other rules. When you move a rule from the top or middle to the bottom, the system shifts all rules above the bottom up to the position of the rule that you moved. When you move a rule from the bottom or middle to the top, the system shifts all rules below down to the position of the rule that you moved. Positions start from 1.

A valid from-index and to-index are required to be supplied as arguments to the move action. If you enter a range that is out of bounds for either the from-index or to-index, the ACLI informs you that the command did not execute and the reason.

If you create an invalid sip-manipulation by incorrectly ordering the manipulation rules, the Oracle Enterprise Communications Broker validates the rules at configuration time and treats them as invalid prior to runtime. This may or may not affect the outcome of the sip-manipulation as a configured rule may not perform any operation if it refers to a rule that has yet to be executed. It is your responsibility to reorder the remaining rules in order to make the sip-manipulation valid again.

Note that rules of a different type at the same level are all part of the same list. Header-rules, mime-rules, mime-isup-rules, and mime-sdp-rules all share the same configuration level under sip-manipulation. When selecting a move from-index and to-index for a header-rule, you must take into consideration the location of all other rules at the same level because the move is relative to all rules at that level. The move is not relative to the particular rule you selected (for example, the header-rule).

Because the list of rules at any one level can be lengthy, you can issue the move command one argument at a time, providing you with the ability to select indices. For example, typing move without any arguments displays the list of all the rules at that level. After selecting an appropriate index, the system prompts you with a to-index location based on the same list provided.

For Example:

ORACLE(sip-mime-sdp-rules)# move
select a rule to move

1: msr sdp-type=any; action=none; match-value=; msg-type=any

2: addFoo header-name=Foo; action=none; match-value=; msg-type=any

3: addBar header-name=Bar; action=none; match-value=; msg-type=any

selection: 2
destination: 1
Rule moved from position 2 to position 1
ACMEPACKET(sip-mime-sdp-rules)#

Rule Nesting and Management

There will be cases where the user wants to take a stored value from the SDP and place it in a SIP header, and vice-versa. All header-rules, element-rules, mime-rules, mime-isup-rules, isup-param-rules, mime-header-rules and mime-sdp-rules are inherited from a Manipulation Rule. A Sip Manipulation is of type Manipulation which contains a list of Manipulation Rules. Each Manipulation Rule can itself contain a list of Manipulation Rules. Therefore when configuring manipulation rules, they will be saved in the order which they have been configured. This is different from the way other configuration objects are configured. Essentially, the user has the option of configuring which type of object they want and when they are done, it gets added to the end of the sip-manipulation, such that order is preserved. This will mean that any Manipulation Rule at the same level can not share the same name. For example, names of header-rules can’t be the same as any of the mime-sdp-rule ones or mime-isup-rule. This allows the user to reference stored values from one rule type in another at the same level.

ACLI Configuration Examples

The following eight sections provide sample SDP manipulations.

Remove SDP

sip-manipulation
        name                      stripSdp
        description               remove SDP from SIP message
        mime-sdp-rule
                name                   sdpStrip
                msg-type               request
                methods                INVITE
                action                 delete
                comparison-type        case-sensitive
                match-value
                new-value

Remove Video from SDP

sip-manipulation
        name                        stripVideo
        description                 strip video codecs from SIP
                                    message
        mime-sdp-rule
                name                   stripVideo
                msg-type               request
                methods                INVITE
                action                 manipulate
                comparison-type        case-sensitive
                match-value
                new-value
                sdp-media-rule
                        name              removeVideo
                        media-type        video
                        action            delete
                        comparison-type   case-sensitive
match-value
                        new-value

Add SDP

sip-manipulation
        name                      addSdp
        description               add an entire SDP if one does 
                                  not exist
        mime-sdp-rule
                name                   addSdp
                msg-type               request
                methods                INVITE
                action                 add
                comparison-type        case-sensitive
                match-value
                new-value              “v=0\r\no=mhandley 
2890844526 2890842807 IN IP4 “+$LOCAL_IP+”\r\ns=SDP Seminar\r\ni=A 
Seminar on the session description protocol\r\nu=http: 
//www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.ps\r\ne=mjh@isi.edu 
(Mark Handley)\r\nc=IN IP4 “+$LOCAL_IP+”\r\nt=2873397496 
2873404696\r\na=recvonly\r\nm=audio 49170 RTP/AVP 0\r\n”

Manipulate Contacts

This rule changes the contact in the SDP to the value contained in the Contact header.

sip-manipulation
        name                           changeSdpContact
        description                    changes the contact in the SDP to the value of the contact header
        header-rule
                name                           storeContact
                header-name                    Contact
                action                         store
                comparison-type                pattern-rule
                msg-type                       request
                methods                        INVITE
                match-value                    
                new-value
                element-rule
                        name                           storeHost
                        parameter-name
                        type                           uri-host
                        action                         store
                        match-val-type                 ip
                        comparison-type                pattern-rule
                        match-value
                        new-value
        mime-sdp-rule
                name                           changeConnection
                msg-type                       request
                methods                        INVITE
                action                         manipulate
                comparison-type                case-sensitive
                match-value
                new-value
                sdp-session-rule
                        name                   changeCLine
                        action                 manipulate
                        comparison-type        case-sensitive
                        match-value
                        new-value
                        sdp-line-rule
                           name               updateConnection
                           type               c
                           action             replace
                           comparison-type    case-sensitive
                           match-value        $storeContact.$storeHost
                           new-value          $storeContact.$storeHost.$0

Remove a Codec

This rule changes the contact in the SDP to the value contained in the Contact header.

sip-manipulation
        name                           removeCodec
        description                    remove G711 codec if it exists
        mime-sdp-rule
                name                           removeCodec
                msg-type                       request
                methods                        INVITE
                action                         manipulate
                comparison-type                case-sensitive
                match-value
                new-value
                sdp-media-rule
                        name                       removeG711
                        media-type                 audio
                        action                     manipulate
                        comparison-type            case-sensitive
                        match-value
                        new-value
                        sdp-line-rule
                                name                   remove711
                                type                   m
                                action                 replace
                                comparison-type        pattern-rule
                                match-value            ^(audio [0-9]
                                                       {1,5} RTP.*)( [07]
                                                       \b)(.*)$
                                new-value              $1+$3
                        sdp-line-rule
                                name                   stripAttr
                                type                   a
                                action                 delete
                                comparison-type        pattern-rule
                                match-value            ^(rtpmap|fmtp):
                                                       [07]\b$
                                new-value

Change Codec

sip-manipulation
        name                           convertCodec
        description                    changeG711toG729
        mime-sdp-rule
                name                           changeCodec
                msg-type                       request
                methods                        INVITE
                action                         manipulate
                comparison-type                case-sensitive
                match-value
                new-value
                sdp-media-rule
                        name                     change711to729
                        media-type               audio
                        action                   manipulate
                        comparison-type          case-sensitive
                        match-value
                        new-value
                        sdp-line-rule
                                name                 change711
                                type                 m
                                action               replace
                                comparison-type      pattern-rule
                                match-value          ^(audio [0-9]{4,5} 
                                                     RTP/AVP.*)( 0)(.*)$
new-value            $1+” 18”+$3
                        sdp-line-rule
                                name                 stripAttr
                                type                 a
                                action               delete
                                comparison-type      pattern-rule
                                match-value          ^rtpmap:0 PCMU/
                                                     .+$
                                new-value                      
                        sdp-line-rule
                                name                 addAttr
                                type                 a
                                action               add
                                comparison-type      boolean
                                match-value          $change711to729. 
                                                     $stripAttr
                                new-value            rtpmap:18 G729/8000

Remove Last Codec and Change Port

sip-manipulation
        name                           removeLastCodec
        description                    remove the last codec
        mime-sdp-rule
                name                           removeLastCodec
                msg-type                       request
                methods                        INVITE
                action                         manipulate
                comparison-type                case-sensitive
                match-value
                new-value
                sdp-media-rule
                        name                      removeLast
                        media-type                audio
                        action                    manipulate
                        comparison-type           case-sensitive
                        match-value
                        new-value
                        sdp-line-rule
                                name                   isLastCodec
                                type                   m
                                action                 store
                                comparison-type        pattern-rule
                                match-value            ^(audio )([0-9]{4,
                                                       5})( RTP/AVP 
                                                       [0-9]{1-3})$
new-value
                        sdp-line-rule
                                name                   changePort
                                type                   m
                                action                 replace
                                comparison-type        boolean
                                match-value            $removeLastCodec.
$removeLast.$isLastCodec
                                new-value              $removeLastCodec.
$removeLast.$isLastCodec.$1+0+$removeLastCodec.$removeLast.
$isLastCodec.$3

Remove Codec with Dynamic Payload

sip-manipulation
    name                        removeAMR
    description                 remove the AMR and AMR-WB dynamic codecs
    split-headers                          
    join-headers                            
    mime-sdp-rule
        name                        sdpAMR
        msg-type                    request
        methods                     INVITE
        action                      manipulate
        comparison-type             case-sensitive
        match-value                            
        new-value                              
        sdp-media-rule
            name                        mediaAMR
            media-type                  audio
            action                      manipulate
            comparison-type             case-sensitive
            match-value                            
            new-value                              
            sdp-line-rule
                name                        isAMR
                type                        a
                action                      delete
                comparison-type             pattern-rule
                match-value                 ^rtpmap:([0-9]{2,3}) AMR\/
                new-value                              
        sdp-media-rule
            name                        mediaIsAMR
            media-type                  audio
            action                      manipulate
            comparison-type             boolean
            match-value                 $sdpAMR.$mediaAMR.$isAMR[~]
            new-value                              
            sdp-line-rule
                name                        delFmtpAMR
                type                        a
                action                      delete
                comparison-type             pattern-rule
                match-value                 ^fmtp:({$sdpAMR.$mediaAMR.$isAMR[~].$1})
                new-value                              
            sdp-line-rule
                name                        delAMRcodec
                type                        m
                action                      find-replace-all
                comparison-type             pattern-rule
                match-value                 ^(audio [0-9]+ RTP.*) {$sdpAMR.$mediaAMR.$isAMR[~].$1}(.*)$
                new-value                   $1+$2