/* * Copyright (C) 2005 Luca Veltri - University of Parma - Italy * * This file is part of MjSip (http://www.mjsip.org) * * MjSip is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * MjSip is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MjSip; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author(s): * Luca Veltri (luca.veltri@unipr.it) */ package org.zoolu.sip.provider; import org.zoolu.tools.Configure; import org.zoolu.tools.Parser; import org.zoolu.tools.RotatingLog; import org.zoolu.tools.Timer; /** SipStack includes all static attributes used by the sip stack. * <p> * Static attributes includes the logging configuration, * default SIP port, deafult supported transport protocols, timeouts, etc. */ public class SipStack extends Configure { // ********************** private attributes ********************** /** Whether SipStack configuration has been already loaded */ private static boolean is_init=false; /** The default SipProvider */ //private static SipProvider provider=null; // *********************** software release *********************** /** Release */ public static final String release="mjsip stack 1.6"; /** Authors */ public static final String authors="Luca Veltri - University of Parma (Italy)"; // ********************** static attributes *********************** /** String value "no-ua-info" used for setting no 'User-Agent' header filed. */ //public static final String NO_UA_INFO="NO-UA-INFO"; /** String value "no-server-info" used for setting no 'Server' header filed. */ //public static final String NO_SERVER_INFO="NO-SERVER-INFO"; // ************* default sip provider configurations ************** /** Default SIP port. * Note that this is not the port used by the running stack, but simply the standard default SIP port. * <br> Normally it sould be set to 5060 as defined by RFC 3261. Using a different value may cause * some problems when interacting with other unaware SIP UAs. */ public static int default_port=5060; /** Default supported transport protocols. */ public static String[] default_transport_protocols={ SipProvider.PROTO_UDP, SipProvider.PROTO_TCP }; /** Default max number of contemporary open transport connections. */ public static int default_nmax_connections=32; /** Whether adding 'rport' parameter on via header fields of outgoing requests. */ public static boolean use_rport=true; /** Whether adding (forcing) 'rport' parameter on via header fields of incoming requests. */ public static boolean force_rport=false; // ******************** general configurations ******************** /** default max-forwards value (RFC3261 recommends value 70) */ public static int max_forwards=70; /** starting retransmission timeout (milliseconds); called T1 in RFC2361; they suggest T1=500ms */ public static long retransmission_timeout=500; /** maximum retransmission timeout (milliseconds); called T2 in RFC2361; they suggest T2=4sec */ public static long max_retransmission_timeout=4000; /** transaction timeout (milliseconds); RFC2361 suggests 64*T1=32000ms */ public static long transaction_timeout=32000; /** clearing timeout (milliseconds); T4 in RFC2361; they suggest T4=5sec */ public static long clearing_timeout=5000; /** Whether using only one thread for all timer instances. */ public static boolean single_timer=false; /** Whether 1xx responses create an "early dialog" for methods that create dialog. */ public static boolean early_dialog=false; /** Default 'expires' value in seconds. RFC2361 suggests 3600s as default value. */ public static int default_expires=3600; /** UA info included in request messages in the 'User-Agent' header field. * Use "NONE" if the 'User-Agent' header filed must not be added. */ public static String ua_info=release; /** Server info included in response messages in the 'Server' header field * Use "NONE" if the 'Server' header filed must not be added. */ public static String server_info=release; // ************************ debug and logs ************************ /** Base level (offset) for logging Transport events */ public static int LOG_LEVEL_TRANSPORT=1; /** Base level (offset) for logging Transaction events */ public static int LOG_LEVEL_TRANSACTION=2; /** Base level (offset) for logging Dialog events */ public static int LOG_LEVEL_DIALOG=2; /** Base level (offset) for logging Call events */ public static int LOG_LEVEL_CALL=1; /** Base level (offset) for logging UA events */ public static int LOG_LEVEL_UA=0; /** Log level. Only logs with a level less or equal to this are written. */ public static int debug_level=1; /** Path for the log folder where log files are written. * By default, it is used the "./log" folder. * Use ".", to store logs in the current root folder. */ public static String log_path="log"; /** The size limit of the log file [kB] */ public static int max_logsize=2048; // 2MB /** The number of rotations of log files. Use '0' for NO rotation, '1' for rotating a single file */ public static int log_rotations=0; // no rotation /** The rotation period, in MONTHs or DAYs or HOURs or MINUTEs * examples: log_rotation_time=3 MONTHS, log_rotations=90 DAYS * Default value: log_rotation_time=2 MONTHS */ private static String log_rotation_time=null; /** The rotation time scale */ public static int rotation_scale=RotatingLog.MONTH; /** The rotation time value */ public static int rotation_time=2; // ************************** costructor ************************** /** Parses a single text line (read from the config file) */ protected void parseLine(String line) { String attribute; Parser par; int index=line.indexOf("="); if (index>0) { attribute=line.substring(0,index).trim(); par=new Parser(line,index+1); } else { attribute=line; par=new Parser(""); } char[] delim={' ',','}; // general configurations if (attribute.equals("default_port")) { default_port=par.getInt(); return; } if (attribute.equals("default_transport_protocols")) { default_transport_protocols=par.getWordArray(delim); return; } if (attribute.equals("default_nmax_connections")) { default_nmax_connections=par.getInt(); return; } if (attribute.equals("use_rport")) { use_rport=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("force_rport")) { force_rport=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("max_forwards")) { max_forwards=par.getInt(); return; } if (attribute.equals("retransmission_timeout")) { retransmission_timeout=par.getInt(); return; } if (attribute.equals("max_retransmission_timeout")) { max_retransmission_timeout=par.getInt(); return; } if (attribute.equals("transaction_timeout")) { transaction_timeout=par.getInt(); return; } if (attribute.equals("clearing_timeout")) { clearing_timeout=par.getInt(); return; } if (attribute.equals("single_timer")) { single_timer=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("early_dialog")) { early_dialog=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("default_expires")){ default_expires=par.getInt(); return; } if (attribute.equals("ua_info")) { ua_info=par.getRemainingString().trim(); return; } if (attribute.equals("server_info")) { server_info=par.getRemainingString().trim(); return; } // debug and logs if (attribute.equals("debug_level")) { debug_level=par.getInt(); return; } if (attribute.equals("log_path")) { log_path=par.getString(); return; } if (attribute.equals("max_logsize")) { max_logsize=par.getInt(); return; } if (attribute.equals("log_rotations")) { log_rotations=par.getInt(); return; } if (attribute.equals("log_rotation_time")) { log_rotation_time=par.getRemainingString(); return; } // old parameters if (attribute.equals("host_addr")) printLog("WARNING: parameter 'host_addr' is no more supported; use 'via_addr' instead."); if (attribute.equals("all_interfaces")) printLog("WARNING: parameter 'all_interfaces' is no more supported; use 'host_iaddr' for setting a specific interface or let it undefined."); if (attribute.equals("use_outbound")) printLog("WARNING: parameter 'use_outbound' is no more supported; use 'outbound_addr' for setting an outbound proxy or let it undefined."); if (attribute.equals("log_file")) printLog("WARNING: parameter 'log_file' is no more supported."); } /** Converts the entire object into lines (to be saved into the config file) */ protected String toLines() { // currently not implemented.. return "SipStack/"+release; } /** Costructs a non-static SipStack */ private SipStack() { } /** Inits SipStack */ public static void init() { init(null); } /** Inits SipStack from the specified <i>file</i> */ public static void init(String file) { (new SipStack()).loadFile(file); // user-agent info if (ua_info!=null && (ua_info.length()==0 || ua_info.equalsIgnoreCase(Configure.NONE) || ua_info.equalsIgnoreCase("NO-UA-INFO"))) ua_info=null; // server info if (server_info!=null && (server_info.length()==0 || server_info.equalsIgnoreCase(Configure.NONE) || server_info.equalsIgnoreCase("NO-SERVER-INFO"))) server_info=null; // timers Timer.SINGLE_THREAD=single_timer; // logs if (debug_level>0) { if (log_rotation_time!=null) { SipParser par=new SipParser(log_rotation_time); rotation_time=par.getInt(); String scale=par.getString(); if (scale==null) scale="null"; if (scale.toUpperCase().startsWith("MONTH")) rotation_scale=RotatingLog.MONTH; else if (scale.toUpperCase().startsWith("DAY")) rotation_scale=RotatingLog.DAY; else if (scale.toUpperCase().startsWith("HOUR")) rotation_scale=RotatingLog.HOUR; else if (scale.toUpperCase().startsWith("MINUTE")) rotation_scale=RotatingLog.MINUTE; else { rotation_time=7; rotation_scale=RotatingLog.DAY; printLog("Error with the log rotation time. Logs will rotate every week."); } } } is_init=true; //if (file!=null) printLog("SipStack loaded",1); } /** Whether SipStack has been already initialized */ public static boolean isInit() { return is_init; } // ************************ private methods *********************** /** Logs a string message. */ private static void printLog(String str) { System.out.println("SipStack: "+str); } }