Brekeke SIP Server Dial Plan Plug-in Developer's Guide (C) 2002-2007, Brekeke Software, Inc. All rights reserved. Date: January 12, 2007 This Document explains how to create a Dial Plan Plug-in. Supported version: Brekeke SIP Server 2.0 and later 1. WHAT IS THE DIAL PLAN PLUG-IN? The Dial Plan Plug-in interface provides a way to create your own Dial Plan condition method by using Java. Developers can define more complicated or specified conditions and enhance Dial Plan features by using Dial Plan Plug-ins. 2. HOW TO CREATE A PLUG-IN For building your class, include: \webapps\proxy\WEB-INF\lib\ondosip.jar in the classpath. Please contain a method using the syntax below into your plug-in class. Syntax: static public String methodname( String[] arg, com.brekeke.net.sip.SIPpacket sippacket, Properties pr ) throws Exception or static public boolean methodname( String[] arg, com.brekeke.net.sip.SIPpacket sippacket, Properties pr ) throws Exception Methodname: The methodname should be small letters. Parameters: arg - parameters specified at the Dial Plan sippacket - SIP packet pr - properties Returns: String or boolean If null is returned, the rule will not be matched. The method will be called from the Matching Patterns by specifying "$classname.methodname". How to obtain a SIP header value: String value = sippacket.getValue( "header_name" ) ; e.g: String valueFrom = sippacket.getValue( "From" ) ; How to obtain a property value: String value = pr.getProperty( "key" ) e.g: String valueServerName = pr.getProperty( "sv.name" ) 3. HOW TO INSTALL A PLUG-IN 1)After the compilation is done, please place your class file into: \webapps\proxy\WEB-INF\classes or create a jar file and place it into \webapps\proxy\WEB-INF\lib 2) Specify your plug-in class package path in the property file "sv.properties" which is in \webapps\proxy\WEB-INF\work\sv directory. dialplan.plugins.matching.pkg = For example, if the package path is "com.brekeke.plugin", please add the line below: dialplan.plugins.matching.pkg = com.brekeke.plugin 4. HOW TO CALL A PLUG-IN The plug-in is called by specifying the class name and method name at the Matching Patterns. $classname.methodname If the method has parameters, please specify the parameters as follows: $classname.methodname( parameter ) $classname.methodname( parameter1, parameter2 ) For example, if the classname is "sample" and the method name is "test" and the parameter is To header, the method returns new To header value. ----------------------------------------- [Matching Patterns] $request = ^INVITE $sample.test( To ) = (.+) [Deploy Patterns] To = %1 ----------------------------------------- 5. Sample Code: sample.java package plugin ; import java.util.* ; public class sample { // Parameters: // arg - arguments // sippacket - SIP packet // pr - properties // say hello // // Syntax: // $sample.hello // // Returns: // "hello" static public String hello( String[] arg, com.brekeke.net.sip.SIPpacket sippacket, Properties pr ) throws Exception { // return the string. return ( "hello" ) ; } // reverse string // // Syntax: // $sample.reverse( string ) // // Returns: // reversed string static public String reverse( String[] arg, com.brekeke.net.sip.SIPpacket sippacket, Properties pr ) throws Exception { if ( ( arg != null ) && ( arg[0] != null) ) { String str = arg[0] ; StringBuffer buf = new StringBuffer() ; int m = str.length() - 1; int n ; for ( n = m; n >= 0; --n ) { buf.append( str.charAt( n ) ) ; } return ( buf.toString() ) ; } return ( null ) ; } // get new address based on the username // // Syntax: // $sample.alias( username ) // // Returns: // aliased SIP-URI static public String alias( String[] arg, com.brekeke.net.sip.SIPpacket sippacket, Properties pr ) throws Exception { if ( ( arg != null ) && ( arg[0] != null) ) { String username = arg[0] ; // return original SIP uri based on the username if ( username.equals( "user1" ) ) { return ( "sip:test1@domain1.com" ) ; } if ( username.equals( "user2" ) ) { return ( "sip:test2@domain2.com" ) ; } if ( username.equals( "user3" ) ) { return ( "sip:test3@domain3.com" ) ; } } return ( null ) ; } // get admin's SIP-URI // // Syntax: // $sample.adminuri // // Returns: // admin's SIP-URI static public String adminuri( String[] arg, com.brekeke.net.sip.SIPpacket sippacket, Properties pr ) throws Exception { return ( pr.getProperty( "sv.admin.sip" ) ) ; } // compare strings // // Syntax: // $sample.equals( string1, string2, [string3] ) // // Returns: // "true" or "false" static public boolean equals( String[] arg, com.brekeke.net.sip.SIPpacket sippacket, Properties pr ) throws Exception { if ( ( arg == null ) || ( arg.length < 2 ) ) { return ( true ) ; } int n ; if ( arg[0] == null ) { for ( n = 1; n < arg.length - 1; ++n ) { if ( arg[n] != null ) { return ( false ) ; } } return ( true ) ; } for ( n = 0; n < arg.length - 1; ++n ) { if ( arg[n].equals( arg[n + 1] ) == false ) { return ( false ) ; } } return ( true ) ; } // get uri from the web // // Syntax: // $sample.webget // // Returns: // new SIP-URI static public String webget( String[] arg, com.brekeke.net.sip.SIPpacket sippacket, Properties pr ) throws Exception { // For example, if To header's SIP uri is "sip:username@brekeke.com", // the new SIP uri is obtained from "http://brekeke.com/username.txt". try { // get SIP uri from To header String sipuri = sippacket.getUri( sippacket.getValue( "To" ) ) ; int i = sipuri.indexOf( "@" ) ; if ( i > 0 ) { // get user name String username = sipuri.substring( 4, i ) ; // get domain name String domainname = sippacket.getDomainFromUri( sipuri ) ; // compose the web connection java.net.URL weburl = new java.net.URL( "http://" + domainname + "/" + username + ".txt" ) ; java.io.BufferedReader in = new java.io.BufferedReader( new java.io.InputStreamReader( weburl.openStream() ) ) ; // get new SIP uri String newsipuri = in.readLine().trim() ; in.close(); if ( newsipuri.startsWith( "sip:" ) ) { return ( newsipuri ) ; } } } catch ( Exception ex ) { } return ( null ) ; } } 6. Dial Plan Rule Examples for the sample class Note: For using the sample.java, please specify the variable below in the sv.properties file: dialplan.plugins.matching.pkg = plugin Example-1: $sample.hello ----------------------------------------- [Matching Patterns] $request = ^INVITE $sample.hello = (.+) [Deploy Patterns] To = sip:%1@domain.com ----------------------------------------- The call will be forwarded to sip:hello@domain.com Example-2: $sample.reverse( string ) ----------------------------------------- [Matching Patterns] $request = ^INVITE $geturi( To ) = sip:(.+)@(.+) $sample.reverse( "%1" ) = (.+) [Deploy Patterns] To = sip:%3@%2 ----------------------------------------- The call will be forwarded to the reversed username SIP-URI. For example, if original To header is "sip:1234@domain.com", new To header will be "sip:4321@domain.com". Example-3: $sample.alias( username ) ----------------------------------------- [Matching Patterns] $request = ^INVITE To = sip:(.+)@ $sample.alias( "%1" ) = (.+) [Deploy Patterns] To = %2 ----------------------------------------- The call will be forwarded to the aliased SIP-URI based on the username. Example-4: $sample.adminuri ----------------------------------------- [Matching Patterns] $request = ^INVITE $sample.adminuri = (.+) [Deploy Patterns] To = %1 ----------------------------------------- The call will be forwarded to the adminstrator's SIP-URI. Example-5: $sample.equals( string1, string2, [string3] ) ----------------------------------------- [Matching Patterns] $request = ^INVITE $geturi( From ) = @(.+) $geturi( To ) = @(.+) $sample.equals( "%1", "%2", "domain.com" ) = true [Deploy Patterns] $action = 603 ----------------------------------------- The call will be rejected if a domain name of both From and To headers are same and the domain name is "domain.com". Example-6: $sample.webget ----------------------------------------- [Matching Patterns] $request = ^INVITE $sample.webget = (.+) [Deploy Patterns] To = %1 ----------------------------------------- The call will be forwarded to the new SIP-URI obtained from the web "http://brekeke.com/username.txt".