Methods Summary |
---|
public synchronized void | close()Closes the message channel.
if (0 != useCounter) {
useCounter--;
}
if (0 == useCounter) {
exit();
if (null != messageProcessor) {
((TCPMessageProcessor)messageProcessor).notifyClose(this);
}
}
|
public boolean | equals(java.lang.Object other)Equals predicate.
if (!this.getClass().equals(other.getClass()))
return false;
else {
TCPMessageChannel that = (TCPMessageChannel)other;
if (this.mySock != that.mySock)
return false;
else return true;
}
|
protected synchronized void | exit()Closes the message channel regardless whether it is used or not.
useCounter = 0;
exitFlag = true;
shutDownConnection();
// allow gc to collect MP
messageProcessor = null;
|
public java.lang.String | getKey()Gets an identifying key. This key is used to cache the connection
and re-use it if necessary.
return getKey(peerAddress, peerPort, SIPConstants.TRANSPORT_TCP);
|
public java.lang.String | getPeerAddress()Gets the address of the client that sent the data to us.
return peerAddress;
|
public int | getPeerPort()Gets the port of the peer to whom we are sending messages.
return peerPort;
|
public SIPMessageStack | getSIPStack()Gets my SIP Stack.
return stack;
|
public java.lang.String | getTransport()Gets the transport string.
return SIPConstants.TRANSPORT_TCP;
|
public java.lang.String | getViaHost()Gets the host to assign to outgoing messages.
return myAddress;
|
public int | getViaPort()Gets the port for outgoing messages sent from the channel.
return myPort;
|
public void | handleException(SIPServerException ex)Exception processor for exceptions detected from the application.
// Return a parse error message to the client on the other end
// if he is still alive.
int rc = ex.getRC();
String msgString = ex.getMessage();
if (rc != 0) {
// Do we have a valid Return code ? --
// in this case format the message.
Request request =
(Request) ex.getSIPMessage();
Response response =
request.createResponse(rc);
try {
sendMessage(response);
} catch (IOException ioex) {
if (Logging.REPORT_LEVEL <= Logging.ERROR) {
Logging.report(Logging.ERROR, LogChannels.LC_JSR180,
ioex.getMessage());
}
}
} else {
// Otherwise, message is already formatted --
// just return it
try {
sendMessage(msgString.getBytes());
} catch (IOException ioex) {
if (Logging.REPORT_LEVEL <= Logging.ERROR) {
Logging.report(Logging.ERROR, LogChannels.LC_JSR180,
ioex.getMessage());
}
}
}
|
public void | handleException(ParseException ex, Message sipMessage, java.lang.Class hdrClass, java.lang.String header, java.lang.String message)Exception processor for exceptions detected from the parser. (This
is invoked by the parser when an error is detected).
if (Logging.REPORT_LEVEL <= Logging.ERROR) {
Logging.report(Logging.ERROR, LogChannels.LC_JSR180,
ex.getMessage());
}
// Log the bad message for later reference.
if (hdrClass .equals(FromHeader.clazz) ||
hdrClass.equals(ToHeader.clazz) ||
hdrClass.equals(CSeqHeader.clazz) ||
hdrClass.equals(ViaHeader.clazz) ||
hdrClass.equals(CallIdHeader.clazz) ||
hdrClass.equals(RequestLine.clazz)||
hdrClass.equals(StatusLine.clazz)) {
stack.logBadMessage(message);
throw ex;
} else {
sipMessage.addUnparsed(header);
}
|
public void | handleIOException()Called when the pipelined parser cannot read input because the
other end closed the connection.
if (!exitFlag) {
shutDownConnection();
}
|
protected synchronized void | incrementUseCounter()Increments the number of user of this channel.
if (!exitFlag) {
useCounter++;
}
|
public boolean | isReliable()Returns "true" as this is a reliable transport.
return true;
|
public boolean | isSecure()TCP Is not a secure protocol.
return false;
|
private void | makeSocket(java.lang.String host, int port)Creates a socket connection.
if (host == null ||
host.length() == 0 ||
port < 0) {
throw new IOException("Invalid hostname or port number");
}
String name = "//" + host + ":" + port;
if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
Logging.report(Logging.INFORMATION, LogChannels.LC_JSR180,
"Opening outbound socket connection :" + host + ":" + port);
}
/*
* Original NIST method for opening the socket connection
* has been replaced by direct calls to instantiate the protocol
* handler, in order to pass the security token for use of lower
* level transport connection.
* Original NIST sequence is :
*
* socket = (SocketConnection)Connector.open(name);
*
*/
com.sun.midp.io.j2me.socket.Protocol conn =
new com.sun.midp.io.j2me.socket.Protocol();
try {
mySock = (SocketConnection)conn.openPrim(
stack.getSecurityToken(), name);
} catch (ConnectionNotFoundException ex) {
throw new IOException("Can't connect to "+name);
}
myClientInputStream = mySock.openInputStream();
myClientOutputStream = mySock.openOutputStream();
|
public void | processMessage(Message sipMessage)Gets invoked by the parser as a callback on successful message
parsing (i.e. no parser errors).
if (sipMessage.getFromHeader() == null ||
sipMessage.getTo() == null ||
sipMessage.getCallId() == null ||
sipMessage.getCSeqHeader() == null ||
sipMessage.getViaHeaders() == null) {
String badmsg = sipMessage.encode();
if (Logging.REPORT_LEVEL <= Logging.ERROR) {
ServerLog.logMessage("bad message " + badmsg);
ServerLog.logMessage(">>> Dropped Bad Msg");
}
stack.logBadMessage(badmsg);
return;
}
ViaList viaList = sipMessage.getViaHeaders();
// For a request
// first via header tells where the message is coming from.
// For response, this has already been recorded in the outgoing
// message.
long receptionTime = 0;
if (sipMessage instanceof Request) {
ViaHeader v = (ViaHeader)viaList.first();
if (v.hasPort()) {
peerPort = v.getPort();
} else {
peerPort = SIPConstants.DEFAULT_NONTLS_PORT;
}
peerProtocol = v.getTransport();
// System.out.println("receiver address = " + receiverAddress);
// Foreach part of the request header, fetch it and process it
receptionTime = System.currentTimeMillis();
// This is a request - process the request.
Request sipRequest = (Request)sipMessage;
// Create a new sever side request processor for this
// message and let it handle the rest.
if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
Logging.report(Logging.INFORMATION, LogChannels.LC_JSR180,
"----Processing Message---");
}
SIPServerRequestInterface sipServerRequest =
stack.newSIPServerRequest(sipRequest, this);
try {
sipServerRequest.processRequest(sipRequest, this);
ServerLog.logMessage(sipMessage,
sipRequest.getViaHost() + ":" +
sipRequest.getViaPort(),
stack.getHostAddress() + ":" +
stack.getPort(this.getTransport()),
false,
receptionTime);
} catch (SIPServerException ex) {
ServerLog.logMessage(sipMessage,
sipRequest.getViaHost() + ":"
+ sipRequest.getViaPort(),
stack.getHostAddress() + ":" +
stack.getPort(this.getTransport()),
ex.getMessage(), false, receptionTime);
handleException(ex);
}
} else {
// This is a response message - process it.
Response sipResponse = (Response)sipMessage;
SIPServerResponseInterface sipServerResponse =
stack.newSIPServerResponse(sipResponse, this);
if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
Logging.report(Logging.INFORMATION, LogChannels.LC_JSR180,
"got a response interface " + sipServerResponse);
}
try {
sipServerResponse.processResponse(sipResponse, this);
} catch (SIPServerException ex) {
// An error occured processing the message -- just log it.
ServerLog.logMessage(sipMessage,
getPeerAddress().toString() + ":"
+ getPeerPort(),
stack.getHostAddress() + ":" +
stack.getPort(this.getTransport()),
ex.getMessage(), false, receptionTime);
// Ignore errors while processing responses??
}
}
|
private void | reConnect()Reconnect to the server.
shutDownConnection();
makeSocket(peerAddress, peerPort);
myParser = new PipelinedMsgParser(this, myClientInputStream);
myParser.processInput();
|
private synchronized void | sendMessage(byte[] msg)Sends message to whoever is connected to us.
Uses the topmost via address to send to.
if (exitFlag) {
return;
}
if (mySock == null) {
reConnect();
}
myClientOutputStream.write(msg);
|
public void | sendMessage(Message sipMessage)Returns a formatted message to the client.
We try to re-connect with the peer on the other end if possible.
if (sipMessage == null) {
throw new NullPointerException("null arg!");
}
byte[] msg = sipMessage.encodeAsBytes();
long time = System.currentTimeMillis();
sendMessage(msg);
if (ServerLog.needsLogging(ServerLog.TRACE_MESSAGES)) {
logMessage(sipMessage, peerAddress, peerPort, time);
}
|
public void | sendMessage(byte[] message, java.lang.String receiverAddress, int receiverPort)Sends a message to a specified address.
if (message == null || receiverAddress == null) {
throw new IllegalArgumentException("Null argument");
}
if (!receiverAddress.equals(peerAddress) || peerPort != receiverPort) {
throw new IOException("This channel is bound to different peer");
}
sendMessage(message);
|
private synchronized void | shutDownConnection()Closes all input and output stream and socket.
try {
if (null != myClientInputStream) {
myClientInputStream.close();
}
} catch (IOException ioe) {
// intentionally ignored
}
try {
if (null != myClientOutputStream) {
myClientOutputStream.close(); }
} catch (IOException ioe) {
// intentionally ignored
}
try {
if (null != mySock) {
mySock.close();
}
} catch (IOException ioe) {
// intentionally ignored
}
// null mySock indicates closed connection
// see sendMessage()
mySock = null;
|
private void | start()This gets invoked when thread.start is called from the constructor.
Implements a message loop - reading the tcp connection and processing
messages until we are done or the other end has closed.
// Create a pipelined message parser to read and parse
// messages that we write out to him.
myParser = new PipelinedMsgParser(this, myClientInputStream);
// Enable the flag to parse message content.
// Start running the parser thread.
myParser.processInput();
|