package local.server; import org.zoolu.sip.provider.SipStack; import org.zoolu.sip.header.StatusLine; import org.zoolu.sip.message.Message; import org.zoolu.sip.message.SipMethods; import org.zoolu.tools.Log; import org.zoolu.tools.DateFormat; import java.util.Hashtable; import java.util.Vector; import java.util.Date; /** CallLoggerImpl implements a simple CallLogger. * <p> A CallLogger keeps trace of all processed calls. */ public class CallLoggerImpl implements CallLogger { /** Maximum number of concurrent calls. */ static final int MAX_SIZE=10000; /** Table : call_id (String) --> invite date. */ Hashtable invite_dates; /** Table : call_id (String) --> 2xx date (Long). */ Hashtable accepted_dates; /** Table : call_id (String) --> 4xx date (Long). */ Hashtable refused_dates; /** Table : call_id (String) --> bye date (Long). */ Hashtable bye_dates; /** Table : call_id (String) --> caller (String). */ Hashtable callers; /** Table : call_id (String) --> callee (String). */ Hashtable callees; /** Set : call_id (String). */ Vector calls; /** Logger. */ Log call_log; /** Costructs a new CallLoggerImpl. */ public CallLoggerImpl(String filename) { invite_dates=new Hashtable(); accepted_dates=new Hashtable(); refused_dates=new Hashtable(); bye_dates=new Hashtable(); calls=new Vector(); callers=new Hashtable(); callees=new Hashtable(); call_log=new Log(filename,null,1,-1,true); call_log.println("Date \tCall-Id \tStatus \tCaller \tCallee \tSetup Time \tCall Time"); } /** Updates log with the present message. */ public void update(Message msg) { String method=msg.getCSeqHeader().getMethod(); String call_id=msg.getCallIdHeader().getCallId(); if (method.equalsIgnoreCase(SipMethods.INVITE)) { if (msg.isRequest()) { if (!invite_dates.containsKey(call_id)) { Date time=new Date(); String caller=msg.getFromHeader().getNameAddress().getAddress().toString(); String callee=msg.getToHeader().getNameAddress().getAddress().toString(); insert(invite_dates,call_id,time); callers.put(call_id,caller); callees.put(call_id,callee); eventlog(time,call_id,SipMethods.INVITE,caller,callee); } } else { StatusLine status_line=msg.getStatusLine(); int code=status_line.getCode(); if (code>=200 && code<300 && !accepted_dates.containsKey(call_id)) { Date time=new Date(); insert(accepted_dates,call_id,time); String reason=status_line.getReason(); eventlog(time,call_id,String.valueOf(code)+" "+reason,"",""); } else if (code>=300 && !refused_dates.containsKey(call_id)) { Date time=new Date(); insert(refused_dates,call_id,time); String reason=status_line.getReason(); eventlog(time,call_id,String.valueOf(code)+" "+reason,"",""); } } } else if (method.equalsIgnoreCase(SipMethods.BYE)) { if (msg.isRequest()) { if (!bye_dates.containsKey(call_id)) { Date time=new Date(); insert(bye_dates,call_id,time); eventlog(time,call_id,SipMethods.BYE,"",""); calllog(call_id); } } } } /** Insters/updates a call-state table. */ private void insert(Hashtable table, String call_id, Date time) { if (!invite_dates.containsKey(call_id) && !accepted_dates.containsKey(call_id) && !refused_dates.containsKey(call_id) && !bye_dates.containsKey(call_id)); { if (calls.size()>=MAX_SIZE) { String call_0=(String)calls.elementAt(0); invite_dates.remove(call_0); accepted_dates.remove(call_0); refused_dates.remove(call_0); bye_dates.remove(call_0); callers.remove(call_0); callees.remove(call_0); calls.removeElementAt(0); } calls.addElement(call_id); } table.put(call_id,time); } /** Prints a generic event log. */ private void eventlog(Date time, String call_id, String event, String caller, String callee) { //call_log.println(DateFormat.formatHHMMSS(time)+"\t"+call_id+"\t"+event+"\t"+caller+"\t"+callee); call_log.println(DateFormat.formatYYYYMMDD(time)+"\t"+call_id+"\t"+event+"\t"+caller+"\t"+callee); } /** Prints a call report. */ private void calllog(String call_id) { Date invite_time=(Date)invite_dates.get(call_id); Date accepted_time=(Date)accepted_dates.get(call_id); Date bye_time=(Date)bye_dates.get(call_id); if (invite_time!=null && accepted_time!=null && bye_time!=null) //call_log.println(DateFormat.formatHHMMSS(invite_time)+"\t"+call_id+"\tCALL \t"+callers.get(call_id)+"\t"+callees.get(call_id)+"\t"+(accepted_time.getTime()-invite_time.getTime())+"\t"+(bye_time.getTime()-accepted_time.getTime())); call_log.println(DateFormat.formatYYYYMMDD(invite_time)+"\t"+call_id+"\tCALL \t"+callers.get(call_id)+"\t"+callees.get(call_id)+"\t"+(accepted_time.getTime()-invite_time.getTime())+"\t"+(bye_time.getTime()-accepted_time.getTime())); } }