📄 mymessenger.java
字号:
/*
* Copyright (C) 2000 Neil Deason
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
* Author's Address
*
* Neil Deason
* Ubiquity Software Corporation
* Ubiquity House
* Langstone Park
* Newport
* South Wales
* NP18 2LH
*/
import java.io.*;
import java.net.*;
import java.util.*;
/***************************************************************************************/
/**
* This interface allows notification of incmong messages to an instance
* of the Messenger class.
*/
interface MyMessengerObserver
{
public void notify(DatagramPacket datapacket);
}
/***************************************************************************************/
/***************************************************************************************/
/**
* A Class that manipulates the MyMsg Object
* to build the desired SIP Message.
*/
class MyMsgBuilder
{
private static String VRDNIP="218.19.145.112";
private static String SIPIP="218.19.145.108";
// Constructor
MyMsgBuilder()
{
printDebug("MyMsgBuilder Initiated");
}
// Constructor
MyMsgBuilder(String strVRDN, String strSIP)
{
VRDNIP=strVRDN;
SIPIP=strSIP;
printDebug("MyMsgBuilder Initiated");
}
// Debug Print
static private void printDebug(String MsgToPrint)
{
if(m_Debug)
System.out.println(MsgToPrint);
}
// Debug flags
static private boolean m_Debug;
static public void setDebug(boolean flag)
{
m_Debug=flag;
}
static public boolean getDebug()
{
return m_Debug;
}
// To be verified....
public static void addSDP(MyMsg IncMsg, MyMsg OutMsg)
{
byte[] LF=new byte[2];
LF[0]=0x0D;
LF[1]=0x0A;
String LineF=new String(LF);
String oBody = OutMsg.toString();
// To trim the pending LF.
// But presently, this while loop does not seem to work.
while(oBody.endsWith(LineF))
{
printDebug("Code Trim Space Executed");
oBody=oBody.substring(0,oBody.length()-2);
}
String LineSDP=IncMsg.getSDP();
Integer tmp=new Integer(LineSDP.length());
String LineCon="Content-Type:application/sdp; charset=ISO10646";
String LineLen="Content-Length:"+tmp.toString();
oBody=oBody+LineF+LineCon+LineF+LineLen+LineF+LineF+IncMsg.getSDP()+LineF+LineF;
// A blank line to separate the Header(Various headers) from BODY(SDP).
OutMsg.setBody(oBody);
}
// To be verified....
public static void addCallID(String CallID, MyMsg OutMsg)
{
byte[] LF=new byte[2];
LF[0]=0x0D;
LF[1]=0x0A;
String LineF=new String(LF);
String oBody = OutMsg.toString();
// To trim the pending LF.
while(oBody.endsWith(LineF))
{
oBody=oBody.substring(0,oBody.length()-2);
}
oBody=oBody+CallID+LineF+LineF;
OutMsg.setBody(oBody);
}
/** this is merely a test method to figure out what response is expected by GWC
* And should not be regarded as a method to use when doing SIP verification.
*
* :p IT WORKS!!
* If a message follows the following format, it will be recognized by CS2Kc.
* LineFeed to terminate a Header
* Double LineFeed to terminate a Message.
* A Blank line to seperate the Message Header and the Msg Body.
*
*/
public static MyMsg build100(MyMsg InvMsg)
{
byte[] LF=new byte[2];
LF[0]=0x0D;
LF[1]=0x0A;
String LineF=new String(LF);
if(InvMsg == null)
return null;
printDebug("Start Building 100 Msg");
String Line100="SIP/2.0 100 Trying";
String LineVia=InvMsg.getVia();
String LineTo=InvMsg.getTo();
String LineFrom=InvMsg.getFrom();
String LineCallID=InvMsg.getCallID();
String LineCSeq=InvMsg.getCseq();
String LineLen="Content-Length:0";
//Start to build response.
String strBody=Line100+LineF+LineVia+LineF+LineTo+LineF+LineFrom+LineF+LineCallID+LineF+LineCSeq+LineF+LineLen+LineF+LineF;
MyMsg OutMsg=new MyMsg(strBody);
printDebug("100 Msg Built");
return OutMsg;
}
/*
public static MyMsg buildPRACK(MyMsg InvMsg, MyMsg In18xMsg)
{
byte[] LF=new byte[2];
LF[0]=0x0D;
LF[1]=0x0A;
String LineF=new String(LF);
if(InMsg == null)
return null;
printDebug("Start Building PRACK Msg");
String Line100="PRACK "+InvMsg.getURI();
String LineVia=In18xMsg.getVia();
String LineTo=In18xMsg.getTo();
String LineFrom=In18xMsg.getFrom();
String LineCallID=In18xMsg.getCallID();
String LineCSeq=In18xMsg.getCseq();
String LineRAckTmp=In18xMsg().getRseq();
StringTokenizer st_Rack=new StringTokenizer(LineRAckTmp);
String LineLen="Content-Length:0";
//Start to build response.
String strBody=Line100+LineF+LineVia+LineF+LineTo+LineF+LineFrom+LineF+LineCallID+LineF+LineCSeq+LineF+LineLen+LineF+LineF;
MyMsg OutMsg=new MyMsg(strBody);
printDebug("100 Msg Built");
return OutMsg;
}
*/
/** this is merely a test method to figure out whether my understanding of the S
* SIP protocol is corrrect. In no case should this method be called during a
* SIP protocol verification.
*/
public static MyMsg buildInv()
{
byte[] LF=new byte[2];
LF[0]=0x0A;
LF[1]=0x0D;
String LineF=new String(LF);
printDebug("Start Building Inv Msg");
String LineMethod="INVITE sip:8302118@"+SIPIP+" SIP/2.0";
String LineVia="Via:SIP/2.0/UDP SIPTESTER";
String LineCallID="Call-ID:2002-08-07-1745@SIPTESTER";
String LineTo="To:<sip:8302118@MGCA;user=phone>";
String LineFrom="From:<sip:08806@SIPTESTER;user=phone>";
String LineContact="Contact:<sip:08806@SIPTESTER;user=phone>";
String LineRemote="Remote-Party-ID:<sip:8806@SIPTESTER;user=phone>;party=calling;id-type=subscriber";
String LineProf="X-Nortel-Profile:SIPTESTPROF";
String LineCSeq="CSeq:1 INVITE";
String LineSupport="Supported:100rel";
String LinePayload="Content-Type:application/sdp; charset=ISO10646";
String SDP1="v=0";
String SDP2="c=IN IP4 202.38.32.112";
String SDP3="m=audio 10000 RTP/AVP 8";
String SDP4="a=ptime:20";
Integer tmp=new Integer(SDP1.length()+2+SDP2.length()+2+SDP3.length()+2+SDP4.length());
// 2 for CRLF
String LineLen="Content-Length:"+tmp.toString();
String Msg=LineMethod+LineF+LineCallID+LineF+LineVia+LineF+LineTo+LineF+LineFrom+LineF+LineContact+LineF+LineProf+LineF+LineCSeq+LineF+LineSupport+LineF+LinePayload+LineF+LineLen+LineF+LineF+SDP1+LineF+SDP2+LineF+SDP3+LineF+SDP4+LineF+LineF+LineF;
printDebug("INVITE Built");
MyMsg mymsg = new MyMsg(Msg);
return mymsg;
}
public static MyMsg build200Bye(MyMsg IncMsg)
{
byte[] LF=new byte[2];
LF[0]=0x0D;
LF[1]=0x0A;
String LineF=new String(LF);
if(IncMsg == null)
return null;
printDebug("Start Building 200 Msg");
String Line200="SIP/2.0 200 OK";
String LineVia=IncMsg.getVia();
String LineTo=IncMsg.getTo();
String LineFrom=IncMsg.getFrom();
String LineCallID=IncMsg.getCallID();
String LineCSeq=IncMsg.getCseq();
String LineLen="Content-Length:0";
//Start to build response.
String strBody=Line200+LineF+LineVia+LineF+LineTo+LineF+LineFrom+LineF+LineCallID+LineF+LineCSeq+LineF+LineLen+LineF+LineF;
MyMsg OutMsg=new MyMsg(strBody);
printDebug("200 Msg Built");
return OutMsg;
}
public static MyMsg buildOptionsResp100(MyMsg msg)
{
byte[] Delimer = new byte[2];
Delimer[0]=0x0D;
Delimer[1]=0x0A;
String LineFeed=new String(Delimer);
boolean MsgComplete=false;
String LineFrom=msg.getFrom();
String LineTo=msg.getTo();
String CallID=msg.getCallID();
String LineSupport="Supported:com.nortelnetworks.firewall,100rel";
String LineVia=msg.getVia()+";received="+VRDNIP;
String LineCseq=msg.getCseq();
String ContentLength="Content-Length:0";
String Server="Server:IMS1.0";
String My100Msg="SIP/2.0 100 Trying";
String strMyMsg=null;
if((LineFrom != null) && (LineTo != null) && (CallID != null))
{
//Build 100
strMyMsg=My100Msg+LineFeed+LineVia+LineFeed+LineTo+LineFeed+LineFrom+LineFeed+CallID+LineFeed+LineCseq+LineFeed+LineSupport+LineFeed+ContentLength+LineFeed+Server+LineFeed+LineFeed;
}
MyMsg outMsg=new MyMsg(strMyMsg);
return outMsg;
}
public static MyMsg buildOptionsResp200(MyMsg msg)
{
byte[] Delimer = new byte[2];
Delimer[0]=0x0D;
Delimer[1]=0x0A;
String LineFeed=new String(Delimer);
boolean MsgComplete=false;
String LineFrom=msg.getFrom();
String LineTo=msg.getTo();
String CallID=msg.getCallID();
String LineSupport="Supported:com.nortelnetworks.firewall,100rel";
String LineVia=msg.getVia()+";received="+VRDNIP;
String LineCseq=msg.getCseq();
String ContentLength="Content-Length:0";
String Server="Server:IMS1.0";
String My200Msg="SIP/2.0 200 OK";
String strMyMsg=null;
if((LineFrom != null) && (LineTo != null) && (CallID != null))
{
//Build 200
Calendar Cc=Calendar.getInstance();
long MyTimeStamp=(Cc.get(Calendar.MONTH)+1)*60*60*24*30+Cc.get(Calendar.DAY_OF_MONTH)*60*60*24+Cc.get(Calendar.HOUR_OF_DAY)*60*60+Cc.get(Calendar.MINUTE)*60+Cc.get(Calendar.SECOND);
LineTo=msg.getTo()+";tag:"+MyTimeStamp;
strMyMsg=My200Msg+LineFeed+LineVia+LineFeed+LineTo+LineFeed+LineFrom+LineFeed+CallID+LineFeed+LineCseq+LineFeed+LineSupport+LineFeed+ContentLength+LineFeed+Server+LineFeed+LineFeed;
}
MyMsg outMsg = new MyMsg(strMyMsg);
return outMsg;
}
/**
* Due to the limited timeframe, It is not possible for me to put the code to handle
* the registration/deregistration request in this release.
* However, the underlying protocol details are known now.
* Register:
* Client send "REGISTER" request with the EXPIRES header, in which contains the
* time it requested for this session.(in seconds.)(e.g. expires:3600)
* Server respond with a 100 trying to stop the retransmission of the REGISTER request
* then respond with a 200 OK msg in which the CONTACT header in the request are modified
* ANd "q=0.0" and "expires=3600"(extracted from the expires header) are pended.
* And the registration is finished.
*
* Deregister:
* Client send a "REGISTER" with EXPIRES header set to 0.(session will be expire in 0 seconds.)
* The server respond with "100 Trying" then "200 OK"(Without Contact Header!)
*/
public static MyMsg buildRegisterResp200(MyMsg msg)
{
byte[] Delimer = new byte[2];
Delimer[0]=0x0D;
Delimer[1]=0x0A;
String LineFeed=new String(Delimer);
String Line200="SIP/2.0 200 Registration Successful";
String LineVia = msg.getVia();
String LineTo = msg.getTo();
String LineFrom = msg.getFrom();
String LineCallID = msg.getCallID();
String LineCseq = msg.getCseq();
String LineSupported = "Supported:com.nortelnetworks.firewall, 100rel";
String LineConLen = "Content-Length:0";
String LineServer="Server:IMS 1.0";
// To simplify the implementation, the following lines are hard-coded.....
// Anyway, we just want to have the SIP CLIENT register, right..:)
String LineContact="Contact:<sip:benxu@nortelnetworks.com;transport=udp;nt_disposition=firewall_client>;q=0.0;expires=3600";
String LineMaxFwd="Max-Forwards: 20";
String strBody=Line200+LineFeed+LineVia+LineFeed+LineTo+LineFeed+LineFrom+LineFeed+LineCallID+LineFeed+LineCseq+LineFeed+LineSupported+LineFeed+LineConLen+LineFeed+LineServer+LineFeed+LineContact+LineFeed+LineMaxFwd+LineFeed+LineFeed;
MyMsg oMsg = new MyMsg(strBody);
return oMsg;
}
public static MyMsg buildRegisterResp100(MyMsg msg)
{
byte[] Delimer = new byte[2];
Delimer[0]=0x0D;
Delimer[1]=0x0A;
String LineFeed=new String(Delimer);
String Line100="SIP/2.0 100 Trying";
String LineVia = msg.getVia();
String LineTo = msg.getTo();
String LineFrom = msg.getFrom();
String LineCallID = msg.getCallID();
String LineCseq = msg.getCseq();
String LineSupported = "Supported:com.nortelnetworks.firewall, 100rel";
String LineConLen = "Content-Length:0";
String LineServer="Server:IMS 1.0";
String strBody=Line100+LineFeed+LineVia+LineFeed+LineTo+LineFeed+LineFrom+LineFeed+LineCallID+LineFeed+LineCseq+LineFeed+LineSupported+LineFeed+LineConLen+LineFeed+LineServer+LineFeed+LineFeed;
MyMsg oMsg = new MyMsg(strBody);
return oMsg;
}
}
/***************************************************************************************/
/***************************************************************************************/
/**
* SIP Message Object
* Following Rules are to be followed if a message be recognized by CS2Kc.
* =============================================================
* LineFeed to terminate a Header
* Double LineFeed to terminate a Message.
* A Blank line to seperate the Message Header and the Msg Body.
* =============================================================
*/
class MyMsg
{
// The Body field of the MyMsg Class contains the full message.
private String Body;
// The following fields will be filled automatically using myMsgParser method
private String MySDP;
private String MyMethod;
private String MyCallID;
private String MyCseq;
private String MyFrom;
private String MyTo;
private String MyVia;
private String MyBoundary;
private String MyURI;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -