Thread: [Asterisk-java-cvs] CVS: asterisk-java/src/java/net/sf/asterisk/manager DefaultManagerConnection.jav
Brought to you by:
srt
From: Stefan R. <sr...@us...> - 2005-03-02 00:38:01
|
Update of /cvsroot/asterisk-java/asterisk-java/src/java/net/sf/asterisk/manager In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30168/src/java/net/sf/asterisk/manager Modified Files: DefaultManagerConnection.java Log Message: Synchronized access to socket and writer Index: DefaultManagerConnection.java =================================================================== RCS file: /cvsroot/asterisk-java/asterisk-java/src/java/net/sf/asterisk/manager/DefaultManagerConnection.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -p -r1.2 -r1.3 --- DefaultManagerConnection.java 23 Feb 2005 22:50:57 -0000 1.2 +++ DefaultManagerConnection.java 2 Mar 2005 00:37:38 -0000 1.3 @@ -53,6 +53,9 @@ import org.apache.commons.logging.LogFac */ public class DefaultManagerConnection implements ManagerConnection { + /** + * Instance logger. + */ private final Log logger = LogFactory.getLog(getClass()); private long actionIdCount = 0; @@ -70,7 +73,6 @@ public class DefaultManagerConnection im private PrintWriter writer; private ActionBuilder actionBuilder = new ActionBuilder(); private String protocolIdentifier; - private String challenge; private Map responseHandlers = new HashMap(); private Collection eventHandlers = new HashSet(); private boolean keepAlive = false; @@ -175,7 +177,7 @@ public class DefaultManagerConnection im * login is delayed until the protocol identifier has been received by the reader. * * @throws AuthenticationFailedException if the username and/or password are incorrect - * @throws TimeoutException if there no response is received within the specified timeout period + * @throws TimeoutException if no response is received within the specified timeout period * * @see ChallengeAction * @see LoginAction @@ -185,15 +187,34 @@ public class DefaultManagerConnection im login(defaultTimeout); } + /** + * Does the real login, following the steps outlined below.<br> + * <ol> + * <li>Connects to the asterisk server by calling {@link #connect()} if not already connected + * <li>Waits until the protocol identifier is received. This is checked every + * {@link #sleepTime} ms but not longer than timeout ms in total. + * <li>Sends a {@link ChallengeAction} requesting a challenge for authType MD5. + * <li>When the {@link ChallengeResponse} is received a {@link LoginAction} is sent using the + * calculated key (MD5 hash of the password appended to the received challenge). + * </ol> + * + * @param timeout the maximum time to wait for the protocol identifier (in ms) + * @throws AuthenticationFailedException if username or password are incorrect and the login + * action returns an error or if the MD5 hash cannot be computed. The connection is closed in + * this case. + * @throws TimeoutException if a timeout occurs either while waiting for the protocol identifier + * or when sending the challenge or login action. The connection is closed in this case. + */ private void login(long timeout) throws IOException, AuthenticationFailedException, TimeoutException { long timeSpent; ChallengeAction challengeAction; ChallengeResponse challengeResponse; + String challenge; LoginAction loginAction; ManagerResponse loginResponse; - if (socket == null) + if (!isConnected()) { connect(); } @@ -236,7 +257,6 @@ public class DefaultManagerConnection im } catch (NoSuchAlgorithmException ex) { - logger.error("Unable to create login key using MD5 Message Digest", ex); disconnect(); throw new AuthenticationFailedException("Unable to create login key using MD5 Message Digest", ex); } @@ -244,7 +264,6 @@ public class DefaultManagerConnection im loginResponse = sendAction(loginAction); if (loginResponse instanceof ManagerError) { - logger.info("Authentication failed: " + loginResponse.getMessage()); disconnect(); throw new AuthenticationFailedException(loginResponse.getMessage()); } @@ -259,7 +278,7 @@ public class DefaultManagerConnection im dispatchEvent(new ConnectEvent(this.asteriskServer)); } - private void connect() throws IOException + private synchronized void connect() throws IOException { BufferedReader bufferedReader; @@ -274,7 +293,23 @@ public class DefaultManagerConnection im this.writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); } - public void logoff() throws IOException, TimeoutException + /** + * Returns <code>true</code> if there is a socket connection to the asterisk server, + * <code>false</code> otherwise. + * + * @return <code>true</code> if there is a socket connection to the asterisk server, + * <code>false</code> otherwise. + */ + protected synchronized boolean isConnected() + { + // return socket != null && socket.isConnected(); // JDK 1.4 + return socket != null; + } + + /** + * Sends a {@link LogoffAction} and disconnects from the server. + */ + public synchronized void logoff() throws IOException, TimeoutException { LogoffAction logoffAction; @@ -282,12 +317,15 @@ public class DefaultManagerConnection im this.keepAlive = false; logoffAction = new LogoffAction(); - sendAction(logoffAction); - - disconnect(); + + if (isConnected()) + { + sendAction(logoffAction); + disconnect(); + } } - private void disconnect() + private synchronized void disconnect() { if (this.writer != null) { @@ -351,6 +389,7 @@ public class DefaultManagerConnection im public void sendAction(ManagerAction action, ManagerResponseHandler callbackHandler) throws IOException { String internalActionId; + String actionString; if (action == null) { @@ -377,16 +416,21 @@ public class DefaultManagerConnection im } } - synchronized (this.writer) + actionString = actionBuilder.buildAction(action); + + synchronized (this) { - String actionString; + if (!isConnected()) + { + throw new IllegalStateException("Unable to send " + action.getAction() + " action: not connected."); + } - actionString = actionBuilder.buildAction(action); this.writer.print(actionString); this.writer.flush(); - - logger.debug("Sent action with internalActionId '" + internalActionId + "':\n" + actionString); } + + logger.debug("Sent " + action.getAction() + " action with internalActionId '" + internalActionId + "':\n" + + actionString); } /** @@ -547,7 +591,7 @@ public class DefaultManagerConnection im */ void setProtocolIdentifier(String protocolIdentifier) { - logger.debug("Received protocol identifier '" + protocolIdentifier + "'"); + logger.info("Connected via " + protocolIdentifier); if (!"Asterisk Call Manager/1.0".equals(protocolIdentifier)) { |