📄 mymessenger.java
字号:
private String MyRseq;
// For IMS
private String MyContact;
private String MyExpire;
// Debug flags
static private boolean m_Debug;
static public void setDebug(boolean flag)
{
m_Debug=flag;
}
static public boolean getDebug()
{
return m_Debug;
}
private void printDebug(String ThisString)
{
if(m_Debug)
System.out.println(ThisString);
}
public String getURI()
{
return MyURI;
}
public String getRseq()
{
return MyRseq;
}
public String getContact()
{
return MyContact;
}
public String getExpire()
{
return MyExpire;
}
public String getSDP()
{
return MySDP;
}
public String getMethod()
{
return MyMethod;
}
public String getCallID()
{
return MyCallID;
}
public String getCseq()
{
return MyCseq;
}
public String getFrom()
{
return MyFrom;
}
public String getTo()
{
return MyTo;
}
public String getVia()
{
return MyVia;
}
public String getBoundary()
{
return MyBoundary;
}
/**
* Constructor
*/
public MyMsg(String strBody)
{
Body=strBody;
if(myMsgParser(Body))
printDebug("MyMsg Object Successfully Created");
}
public void setBody(String strBody)
{
Body=strBody;
if(myMsgParser(Body))
printDebug("MyMsg Object Successfully Modified");
}
public static MyMsg getFromFile(String a_FileName)
{
byte[] buf=null;
try
{
BufferedInputStream buffer = new BufferedInputStream( new FileInputStream(a_FileName) );
int ilength = buffer.available();
buf = new byte[ilength];
buffer.read(buf, 0, ilength);
buffer.close();
}
catch(IOException e)
{
System.out.println(e);
}
String strMsg = new String(buf);
MyMsg msg=new MyMsg(strMsg);
return msg;
}
/**
* A revised version of isOption method .
* 'Cause after introducing the myMsgParser method, the isOption method
* should be able to reuse the code in myMsgParser method.
*/
public boolean isOptions()
{
return (MyMethod.equalsIgnoreCase("OPTIONS"));
}
public boolean isBye()
{
return (MyMethod.equalsIgnoreCase("BYE"));
}
public boolean isInvite()
{
return (MyMethod.equalsIgnoreCase("INVITE"));
}
/**
* This is a method to respond to the SIP Client request.
* Just trying to get to know more about SIP. :p
*/
public boolean isRegister()
{
return (MyMethod.equalsIgnoreCase("REGISTER"));
}
/**
* A very primitive implementation of the toString method
* When this software evolves, I suggested to use the '+' and 'LineFeed'
* to link all the recognized headers together to build the body instead of
* copying the input string.....
*/
public String toString()
{
return Body;
}
/**
* To Parse the SIP message received.
*/
private boolean myMsgParser(String Body)
{
//CRLF
byte[] Delimer = new byte[2];
Delimer[0]=0x0D;
Delimer[1]=0x0A;
String LineFeed=new String(Delimer);
StringTokenizer st_Line = new StringTokenizer(Body, LineFeed);
String ThisLine;
String HeaderPrefix;
// Extract the Method field of the Msg.
if(st_Line.hasMoreTokens())
{
StringTokenizer st_Method = new StringTokenizer(st_Line.nextToken());
if(st_Method.hasMoreTokens())
{
MyMethod = st_Method.nextToken();
if(MyMethod.equalsIgnoreCase("SIP/2.0"))
{
MyURI="NULL";
}
else
{
MyURI=st_Method.nextToken();
}
}
else
{
return false;
}
}
// Parse the rest of the Msg to extract each header.
while(st_Line.hasMoreTokens())
{
ThisLine=st_Line.nextToken();
StringTokenizer st_Word = new StringTokenizer(ThisLine,":");
if(st_Word.hasMoreTokens())
{
HeaderPrefix = st_Word.nextToken();
if(HeaderPrefix.equalsIgnoreCase("FROM"))
{
MyFrom=ThisLine;
}
else if(HeaderPrefix.equalsIgnoreCase("To"))
{
MyTo=ThisLine;
}
else if(HeaderPrefix.equalsIgnoreCase("Via"))
{
MyVia=ThisLine;
}
else if(HeaderPrefix.equalsIgnoreCase("Call-ID"))
{
MyCallID=ThisLine;
}
else if(HeaderPrefix.equalsIgnoreCase("CSeq"))
{
MyCseq=ThisLine;
}
else if(HeaderPrefix.equalsIgnoreCase("RSeq"))
{
MyRseq=ThisLine;
}
else if(HeaderPrefix.equalsIgnoreCase("CONTACT"))
{
MyContact=ThisLine;
}
else if(HeaderPrefix.equalsIgnoreCase("EXPIRES"))
{
MyExpire=ThisLine;
}
// =================================================================
// Potential Error Here....
// Risks :
// 1. Not knowing how to determine the boundary of SDP -- Done by using v=0 as the startline and
// double blank line(IMS) or "-"(CS2Kc) as end line.
// 2. How to distinguish between SDP/ISUP/MIXED -- Done by using substring(0,15).
// 3. How to handle the situation if the boundary is not started with '-'
// 4. How to hadnle the situation if v=0 is not the first parameter in SDP
else if(HeaderPrefix.equalsIgnoreCase("Content-Type"))
{
// String Header = "Media-Type: application/sdp";
// If set to "Content-Type: application/sdp", the GWC does not response at all!
// String Header = "Content-Type: application/sdp";
String ContentType=null;
// Extract the string following the "ContentType" header.
if(st_Word.hasMoreTokens())
{
ContentType = st_Word.nextToken().substring(0,15);
printDebug("ContentType : " + ContentType);
// It is a SDP payload.
if(ContentType.equalsIgnoreCase("application/sdp"))
{
MySDP="";
String LastLine;
while(st_Line.hasMoreTokens())
{
LastLine = ThisLine;
ThisLine = st_Line.nextToken();
// The end of SDP payload...
// The criteria used here is the belief that all the boundary begins with a '-'
// For CS2Kc INVITE.
if(ThisLine.startsWith("-"))
break;
// Do not include any blank line into the SDP field.
// Belief is that the SDP Payload starts with a blank line and ends with '-'.
if(ThisLine.length() != 0)
{
// First line of SDP.
// Belief is that all the SDP payload starts with "v=0".
if(ThisLine.startsWith("v"))
MySDP = ThisLine ;
else
MySDP = MySDP + LineFeed + ThisLine;
}
// Double Linefeed is met. Message ends.
// For IMS INVITE.
else if(LastLine.length()==0)
{
break;
}
}
}
}
}
// =================================================================
}
}
printDebug("===================");
printDebug("MyMethod : "+MyMethod);
printDebug("MyFrom : "+MyFrom);
printDebug("MyTo : "+MyTo);
printDebug("MyVia : "+MyVia);
printDebug("MyCallID : "+MyCallID);
printDebug("MyCSeq : "+MyCseq);
printDebug("MySDP : "+MySDP);
printDebug("===================");
return true;
}
}
/***************************************************************************************/
/***************************************************************************************/
public class MyMessenger implements Runnable, MyMessengerObserver
{
private DatagramSocket m_DatagramSocket;
private Thread m_ListeningThread;
private boolean m_Listening;
private MyMessengerObserver m_Observer;
// Global parameter
static private String VRDNIP;
static private String SIPIP;
static private String LclIP;
static private String RmtPort;
static private String LclPort;
static private String CmdLine;
static private String Cmd;
static private String FileToSend;
static private String MsgToSend;
private MyMsg IncInviteMsg;
private MyMsg LastSndMsg;
private MyMsg LastRevMsg;
private boolean ShowInvite=true;
private boolean ShowSnd=true;
private boolean ShowRev=true;
private boolean AutoAckBye=true;
private boolean AutoAckInv=true;
private String FlagToSet;
private String FileToWrite;
// Running flag to determine whether the program is terminated or not.
private boolean m_Running;
public void setRunning(boolean a_flag)
{
m_Running = a_flag;
}
public boolean getRunning()
{
return m_Running;
}
// set to true to see debug statements
private boolean m_Debugging = false;
public void setDebug(boolean flag)
{
m_Debugging=flag;
}
public boolean getDebug()
{
return m_Debugging;
}
/**
* Construct a new Messenger.
*/
public MyMessenger()
{
// This two lines are added here mainly for version control purpose.
myOutput(">>>>>>>> SIP Debugger <<<<<<<<");
myOutput("Build: 0208220001");
}
/**
* Set the Messenger's observer for notification of any
* incoming messages.
* @param a_Observer an implementer of the MessengerObserver interface.
*/
public void setObserver(MyMessengerObserver a_Observer)
{
m_Observer = a_Observer;
}
/**
* Open a Datagram Socket.
* @param a_Host the host name to open the Datagram Socket on.
* @param a_Port the port to open the Datagram Socket on.
*/
public boolean openDatagramSocket(String a_Host, int a_Port)
{
try
{
printDebug("Getting inetAddress");
InetAddress inetAddress = InetAddress.getByName(a_Host);
printDebug("Got inetAddress");
m_DatagramSocket = new DatagramSocket(a_Port, InetAddress.getByName(a_Host));
printDebug("Opened DatagramSocket on " + a_Host + ":" + a_Port);
// if we have an observer start listening for responses
if( null != m_Observer )
{
m_Listening = true;
m_ListeningThread = new Thread(this);
m_ListeningThread.start();
printDebug("Started listener thread");
}
return true;
}
catch(IOException e)
{
System.out.println("Error opening Datagram Socket " + e);
return false;
}
}
/**
* Close the Datagram Socket.
*/
public void closeDatagramSocket()
{
if ( null != m_DatagramSocket )
{
m_DatagramSocket.close();
m_DatagramSocket = null;
}
}
/**
* A thread to listen for incoming messages and notify the Messenger's
* Observer.
*/
public void run()
{
int packetSize = 1500;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -