asterisk-java-users Mailing List for Asterisk-Java Library (Page 154)
Brought to you by:
srt
You can subscribe to this list here.
2005 |
Jan
|
Feb
(8) |
Mar
(33) |
Apr
(36) |
May
(19) |
Jun
(21) |
Jul
(53) |
Aug
(30) |
Sep
(36) |
Oct
(34) |
Nov
(43) |
Dec
(72) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2006 |
Jan
(123) |
Feb
(75) |
Mar
(86) |
Apr
(46) |
May
(41) |
Jun
(29) |
Jul
(76) |
Aug
(38) |
Sep
(39) |
Oct
(68) |
Nov
(16) |
Dec
(17) |
2007 |
Jan
(34) |
Feb
(18) |
Mar
(39) |
Apr
(30) |
May
(20) |
Jun
(10) |
Jul
(59) |
Aug
(54) |
Sep
(60) |
Oct
(22) |
Nov
(14) |
Dec
(10) |
2008 |
Jan
(34) |
Feb
(67) |
Mar
(65) |
Apr
(67) |
May
(60) |
Jun
(51) |
Jul
(88) |
Aug
(75) |
Sep
(47) |
Oct
(143) |
Nov
(54) |
Dec
(42) |
2009 |
Jan
(46) |
Feb
(80) |
Mar
(162) |
Apr
(159) |
May
(200) |
Jun
(34) |
Jul
(46) |
Aug
(59) |
Sep
(5) |
Oct
(35) |
Nov
(73) |
Dec
(30) |
2010 |
Jan
(23) |
Feb
(50) |
Mar
(8) |
Apr
(24) |
May
(19) |
Jun
(49) |
Jul
(56) |
Aug
(35) |
Sep
(26) |
Oct
(79) |
Nov
(39) |
Dec
(34) |
2011 |
Jan
(27) |
Feb
(22) |
Mar
(28) |
Apr
(12) |
May
(16) |
Jun
(19) |
Jul
(1) |
Aug
(64) |
Sep
(19) |
Oct
(11) |
Nov
(17) |
Dec
(12) |
2012 |
Jan
(6) |
Feb
(8) |
Mar
(15) |
Apr
(43) |
May
(41) |
Jun
(14) |
Jul
(32) |
Aug
(3) |
Sep
(4) |
Oct
(7) |
Nov
(11) |
Dec
(11) |
2013 |
Jan
(35) |
Feb
(11) |
Mar
(23) |
Apr
(25) |
May
(37) |
Jun
(47) |
Jul
(25) |
Aug
(21) |
Sep
|
Oct
(1) |
Nov
(9) |
Dec
|
2014 |
Jan
(26) |
Feb
(2) |
Mar
(18) |
Apr
(41) |
May
(7) |
Jun
(7) |
Jul
(24) |
Aug
(5) |
Sep
(6) |
Oct
(8) |
Nov
(9) |
Dec
(7) |
2015 |
Jan
(7) |
Feb
(15) |
Mar
(8) |
Apr
(12) |
May
(7) |
Jun
|
Jul
|
Aug
(5) |
Sep
(1) |
Oct
(3) |
Nov
(30) |
Dec
(3) |
2016 |
Jan
(1) |
Feb
|
Mar
(2) |
Apr
|
May
(9) |
Jun
|
Jul
|
Aug
(3) |
Sep
|
Oct
|
Nov
|
Dec
|
2017 |
Jan
|
Feb
|
Mar
(3) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
(2) |
Oct
|
Nov
|
Dec
|
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(8) |
Dec
(4) |
2019 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
2020 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(2) |
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Stefan R. <sr...@re...> - 2006-03-16 22:38:52
|
Hi Brett, i am not sure I got what your intention ist. The internal action id should be completely invisible from user's code. As its name implies it is internal to Asterisk-Java. Therefore it is set in ActionWriter and removed in EventBuilder. If your code must make use of the action id itself you can just set your own action id and will get that back (AJ adds its internal action id and strips it from responses and event before passing them to your app resulting in your app always seeing your action id). Regarding the concrete task (originat) a better solution is probably anyway sth like this: OriginateAction originateAction =3D new OriginateAction(); originateAction.setChannel("SIP/1310"); originateAction.setExten("1399"); originateAction.setContext("from-local"); originateAction.setPriority(new Integer(1)); originateAction.setTimeout(new Long(10000)); originateAction.setAsync(Boolean.TRUE); ResponseEvents responseEvents =3D c.sendEventGeneratingAction(originateAction, 30000); for (ManagerEvent event : responseEvents.getEvents()) { if (event instanceof OriginateSuccessEvent) { OriginateSuccessEvent success =3D (OriginateSuccessEvent)= event; System.out.println("Originate was successful: uniqueId " = + success.getUniqueId()); } else if (event instanceof OriginateFailureEvent) { System.out.println("Originate failed"); } } =3DStefan Brett Sutton wrote: > I've been trying to determine a reliable method for matching events to > an originate. > I've experimented with the DefaultManagerConnection Call method, but I'= m > not convinced its reliable (in fact I'm pretty certain it isn't). >=20 > As such I've developed a patch for the DefaultMangerConnection > sendAction method. > The patch basically sets the ActionID of the response object, currently= > it is left as null. > By setting the actionid, and using the Async mode of sendAction which > generates an OriginateSuccessEvent (or failure) I have been able to > retrieve the uniqueid associated with the originate and then use that t= o > match subsequent events. >=20 > Please find the attached update to DefaultManagerConnection. I have als= o > submitted a sample class from AsterFax which demonstrates the technique= > described. >=20 > I believe the patch is non-invasive. >=20 > Regards, > Brett. >=20 >=20 > -----------------------------------------------------------------------= - >=20 > /* > * Copyright 2004-2006 Stefan Reuter > * > * Licensed under the Apache License, Version 2.0 (the "License"); > * you may not use this file except in compliance with the License. > * You may obtain a copy of the License at > * > * http://www.apache.org/licenses/LICENSE-2.0 > * > * Unless required by applicable law or agreed to in writing, software= > * distributed under the License is distributed on an "AS IS" BASIS, > * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or imp= lied. > * See the License for the specific language governing permissions and= > * limitations under the License. > * > */ > package org.asteriskjava.manager; >=20 > import java.io.IOException; > import java.io.Serializable; > import java.security.MessageDigest; > import java.security.NoSuchAlgorithmException; > import java.util.ArrayList; > import java.util.HashMap; > import java.util.List; > import java.util.Map; >=20 > import org.asteriskjava.AsteriskVersion; > import org.asteriskjava.io.SocketConnectionFacade; > import org.asteriskjava.io.impl.SocketConnectionFacadeImpl; > import org.asteriskjava.manager.action.ChallengeAction; > import org.asteriskjava.manager.action.CommandAction; > import org.asteriskjava.manager.action.EventGeneratingAction; > import org.asteriskjava.manager.action.LoginAction; > import org.asteriskjava.manager.action.LogoffAction; > import org.asteriskjava.manager.action.ManagerAction; > import org.asteriskjava.manager.event.ConnectEvent; > import org.asteriskjava.manager.event.DisconnectEvent; > import org.asteriskjava.manager.event.ManagerEvent; > import org.asteriskjava.manager.event.ResponseEvent; > import org.asteriskjava.manager.impl.ManagerReaderImpl; > import org.asteriskjava.manager.impl.ManagerWriterImpl; > import org.asteriskjava.manager.impl.ResponseEventsImpl; > import org.asteriskjava.manager.impl.Util; > import org.asteriskjava.manager.response.ChallengeResponse; > import org.asteriskjava.manager.response.CommandResponse; > import org.asteriskjava.manager.response.ManagerError; > import org.asteriskjava.manager.response.ManagerResponse; > import org.asteriskjava.util.Log; > import org.asteriskjava.util.LogFactory; >=20 >=20 > /** > * Default implemention of the ManagerConnection interface.<br> > * Generelly avoid direct use of this class. Use the ManagerConnectionF= actory to > * obtain a ManagerConnection instead.<br> > * When using a dependency injection framework like Spring direct usage= for > * wiring up beans that require a ManagerConnection property is fine th= ough.<br> > * Note that the DefaultManagerConnection will create one new Thread > * for reading data from Asterisk on the first call to on of the login(= ) > * methods. > *=20 > * @see org.asteriskjava.manager.ManagerConnectionFactory > * @author srt > * @version $Id: DefaultManagerConnection.java,v 1.36 2006/01/10 23:09:= 11 srt Exp $ > */ > public class DefaultManagerConnection implements ManagerConnection, Dis= patcher > { > /** > * Instance logger. > */ > private final Log logger =3D LogFactory.getLog(getClass()); >=20 > /** > * Used to construct the internalActionId. > */ > private long actionIdCount =3D 0; >=20 > /* Config attributes */ > /** > * The Asterisk server to connect to. > */ > private AsteriskServer asteriskServer; >=20 > /** > * The username to use for login as defined in Asterisk's > * <code>manager.conf</code>. > */ > protected String username; >=20 > /** > * The password to use for login as defined in Asterisk's > * <code>manager.conf</code>. > */ > protected String password; >=20 > /** > * The default timeout to wait for a ManagerResponse after sending = a > * ManagerAction. > */ > private long defaultResponseTimeout =3D 2000; >=20 > /** > * The default timeout to wait for the last ResponseEvent after sen= ding an > * EventGeneratingAction. > */ > private long defaultEventTimeout =3D 5000; >=20 > /** > * The timeout to use when connecting the the Asterisk server. > */ > private int socketTimeout =3D 0; >=20 > /** > * The time the calling thread is sleeping between checking if a re= ponse or > * the protocol identifer has been received. > */ > private long sleepTime =3D 50; >=20 > /** > * Should we continue to reconnect after an authentication failure?= > */ > private boolean keepAliveAfterAuthenticationFailure =3D false; >=20 > /** > * The socket to use for TCP/IP communication with Asterisk. > */ > private SocketConnectionFacade socket; >=20 > /** > * The thread that runs the reader. > */ > private Thread readerThread; >=20 > /** > * The reader to use to receive events and responses from asterisk.= > */ > private ManagerReader reader; >=20 > /** > * The writer to use to send actions to asterisk. > */ > private ManagerWriter writer; >=20 > /** > * The protocol identifer Asterisk sends on connect. > */ > private String protocolIdentifier; > =20 > /** > * The version of the Asterisk server we are connected to. > */ > private AsteriskVersion version; >=20 > /** > * Contains the registered handlers that process the ManagerRespons= es.<br> > * Key is the internalActionId of the Action sent and value the > * corresponding ResponseHandler. > */ > private final Map<String, ManagerResponseHandler> responseHandlers;= >=20 > /** > * Contains the event handlers that handle ResponseEvents for the > * sendEventGeneratingAction methods.<br> > * Key is the internalActionId of the Action sent and value the > * corresponding EventHandler. > */ > private final Map<String, ManagerEventHandler> responseEventHandler= s; >=20 > /** > * Contains the event handlers that users registered. > */ > private final List<ManagerEventHandler> eventHandlers; >=20 > /** > * Should we attempt to reconnect when the connection is lost?<br> > * This is set to <code>true</code> after successful login and to > * <code>false</code> after logoff or after an authentication failu= re when > * keepAliveAfterAuthenticationFailure is <code>false</code>. > */ > protected boolean keepAlive =3D false; >=20 > /** > * Creates a new instance. > */ > public DefaultManagerConnection() > { > this.asteriskServer =3D new AsteriskServer(); >=20 > this.responseHandlers =3D new HashMap<String, ManagerResponseHa= ndler>(); > this.responseEventHandlers =3D new HashMap<String, ManagerEvent= Handler>(); > this.eventHandlers =3D new ArrayList<ManagerEventHandler>(); > } >=20 > /** > * Creates a new instance with the given connection parameters. > *=20 > * @param hostname the hostname of the Asterisk server to connect t= o. > * @param port the port where Asterisk listens for incoming Manager= API > * connections, usually 5038. > * @param username the username to use for login > * @param password the password to use for login > */ > public DefaultManagerConnection(String hostname, int port, String u= sername, > String password) > { > this(); >=20 > setHostname(hostname); > setPort(port); > setUsername(username); > setPassword(password); > } >=20 > // the following two methods can be overriden when running test cas= es to > // return a mock object > protected ManagerReader createReader(Dispatcher dispatcher, > AsteriskServer server) > { > return new ManagerReaderImpl(dispatcher, server); > } >=20 > protected ManagerWriter createWriter() > { > return new ManagerWriterImpl(); > } >=20 > /** > * Sets the hostname of the asterisk server to connect to.<br> > * Default is <code>localhost</code>. > *=20 > * @param hostname the hostname to connect to > */ > public void setHostname(String hostname) > { > this.asteriskServer.setHostname(hostname); > } >=20 > /** > * Sets the port to use to connect to the asterisk server. This is = the port > * specified in asterisk's <code>manager.conf</code> file.<br> > * Default is 5038. > *=20 > * @param port the port to connect to > */ > public void setPort(int port) > { > this.asteriskServer.setPort(port); > } >=20 > /** > * Sets the username to use to connect to the asterisk server. This= is the > * username specified in asterisk's <code>manager.conf</code> file.= > *=20 > * @param username the username to use for login > */ > public void setUsername(String username) > { > this.username =3D username; > } >=20 > /** > * Sets the password to use to connect to the asterisk server. This= is the > * password specified in Asterisk's <code>manager.conf</code> file.= > *=20 > * @param password the password to use for login > */ > public void setPassword(String password) > { > this.password =3D password; > } >=20 > /** > * Sets the time in milliseconds the synchronous sendAction methods= > * {@link #sendAction(ManagerAction)} will wait for a response befo= re > * throwing a TimeoutException.<br> > * Default is 2000. > *=20 > * @param defaultTimeout default timeout in milliseconds > * @deprecated use {@link #setDefaultResponseTimeout(long)} instead= > */ > public void setDefaultTimeout(long defaultTimeout) > { > setDefaultResponseTimeout(defaultTimeout); > } >=20 > /** > * Sets the time in milliseconds the synchronous method > * {@link #sendAction(ManagerAction)} will wait for a response befo= re > * throwing a TimeoutException.<br> > * Default is 2000. > *=20 > * @param defaultResponseTimeout default response timeout in millis= econds > * @since 0.2 > */ > public void setDefaultResponseTimeout(long defaultResponseTimeout) > { > this.defaultResponseTimeout =3D defaultResponseTimeout; > } >=20 > /** > * Sets the time in milliseconds the synchronous method > * {@link #sendEventGeneratingAction(EventGeneratingAction)} will w= ait for a > * response and the last response event before throwing a TimeoutEx= ception.<br> > * Default is 5000. > *=20 > * @param defaultEventTimeout default event timeout in milliseconds= > * @since 0.2 > */ > public void setDefaultEventTimeout(long defaultEventTimeout) > { > this.defaultEventTimeout =3D defaultEventTimeout; > } >=20 > /** > * Sets the time in milliseconds the synchronous methods > * {@link #sendAction(ManagerAction)} and > * {@link #sendAction(ManagerAction, long)} will sleep between two = checks > * for the arrival of a response. This value should be rather small= =2E<br> > * The sleepTime attribute is also used when checking for the proto= col > * identifer.<br> > * Default is 50. > *=20 > * @param sleepTime time in milliseconds to sleep between two check= s for the > * arrival of a response or the protocol identifier > * @deprecated this has been replaced by an interrupt based respons= e > * checking approach. > */ > public void setSleepTime(long sleepTime) > { > this.sleepTime =3D sleepTime; > } >=20 > /** > * Set to <code>true</code> to try reconnecting to ther asterisk se= rve > * even if the reconnection attempt threw an AuthenticationFailedEx= ception.<br> > * Default is <code>false</code>. > */ > public void setKeepAliveAfterAuthenticationFailure( > boolean keepAliveAfterAuthenticationFailure) > { > this.keepAliveAfterAuthenticationFailure =3D keepAliveAfterAuth= enticationFailure; > } >=20 > /* Implementation of ManagerConnection interface */ >=20 > public void registerUserEventClass(Class userEventClass) > { > if (reader =3D=3D null) > { > reader =3D createReader(this, asteriskServer); > } >=20 > reader.registerEventClass(userEventClass); > } >=20 > public void setSocketTimeout(int socketTimeout) > { > this.socketTimeout =3D socketTimeout; > } >=20 > public void login() throws IOException, AuthenticationFailedExcepti= on, > TimeoutException > { > login(defaultResponseTimeout, null); > } >=20 > public void login(String events) throws IOException, Authentication= FailedException, > TimeoutException > { > login(defaultResponseTimeout, events); > } >=20 > /** > * 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 che= cked > * every {@link #sleepTime} ms but not longer than timeout ms in to= tal. > * <li>Sends a {@link ChallengeAction} requesting a challenge for a= uthType > * MD5. > * <li>When the {@link ChallengeResponse} is received a {@link Logi= nAction} > * is sent using the calculated key (MD5 hash of the password appen= ded to > * the received challenge). > * </ol> > *=20 > * @param timeout the maximum time to wait for the protocol identif= ier (in > * ms) > * @param events the event mask. Set to "on" if all events should b= e send, > * "off" if not events should be sent or a combination o= f > * "system", "call" and "log" (separated by ',') to spec= ify what > * kind of events should be sent. > * @throws AuthenticationFailedException if username or password ar= e > * incorrect and the login action returns an error or i= f the MD5 > * hash cannot be computed. The connection is closed in= this > * case. > * @throws TimeoutException if a timeout occurs either while waitin= g for the > * protocol identifier or when sending the challenge or= login > * action. The connection is closed in this case. > */ > private void login(long timeout, String events) throws IOException,= > AuthenticationFailedException, TimeoutException > { > long start; > long timeSpent; > ChallengeAction challengeAction; > ChallengeResponse challengeResponse; > String challenge; > String key; > LoginAction loginAction; > ManagerResponse loginResponse; >=20 > if (socket =3D=3D null) > { > connect(); > } >=20 > start =3D System.currentTimeMillis(); > while (getProtocolIdentifier() =3D=3D null) > { > try > { > Thread.sleep(sleepTime); > } > catch (InterruptedException e) > { > } >=20 > timeSpent =3D System.currentTimeMillis() - start; > if (getProtocolIdentifier() =3D=3D null && timeSpent > time= out) > { > disconnect(); > throw new TimeoutException( > "Timeout waiting for protocol identifier"); > } > } >=20 > challengeAction =3D new ChallengeAction("MD5"); > challengeResponse =3D (ChallengeResponse) sendAction(challengeA= ction); >=20 > challenge =3D challengeResponse.getChallenge(); >=20 > try > { > MessageDigest md; >=20 > md =3D MessageDigest.getInstance("MD5"); > if (challenge !=3D null) > { > md.update(challenge.getBytes()); > } > if (password !=3D null) > { > md.update(password.getBytes()); > } > key =3D Util.toHexString(md.digest()); > } > catch (NoSuchAlgorithmException ex) > { > disconnect(); > throw new AuthenticationFailedException( > "Unable to create login key using MD5 Message Diges= t", ex); > } >=20 > loginAction =3D new LoginAction(username, "MD5", key, events); > loginResponse =3D sendAction(loginAction); > if (loginResponse instanceof ManagerError) > { > disconnect(); > throw new AuthenticationFailedException(loginResponse.getMe= ssage()); > } >=20 > // successfully logged in so assure that we keep trying to reco= nnect > // when disconnected > this.keepAlive =3D true; >=20 > logger.info("Successfully logged in"); > =20 > this.version =3D determineVersion(); > this.writer.setTargetVersion(version); > =20 > logger.info("Determined Asterisk version: " + version); > } > =20 > protected AsteriskVersion determineVersion() throws IOException, Ti= meoutException > { > ManagerResponse showVersionFilesResponse; >=20 > // increase timeout as output is quite large > showVersionFilesResponse =3D sendAction(new CommandAction("show= version files pbx.c"),=20 > defaultResponseTimeout * 2); > if (showVersionFilesResponse instanceof CommandResponse) > { > List showVersionFilesResult; > =20 > showVersionFilesResult =3D ((CommandResponse) showVersionFi= lesResponse).getResult(); > if (showVersionFilesResult !=3D null && showVersionFilesRes= ult.size() > 0) > { > String line1; > =20 > line1 =3D (String) showVersionFilesResult.get(0);=20 > if (line1 !=3D null && line1.startsWith("File")) > { > return AsteriskVersion.ASTERISK_1_2; > } > } > } > =20 > return AsteriskVersion.ASTERISK_1_0; > } >=20 > protected synchronized void connect() throws IOException > { > logger.info("Connecting to " + asteriskServer.getHostname() + "= port " > + asteriskServer.getPort()); >=20 > if (this.reader =3D=3D null) > { > this.reader =3D createReader(this, asteriskServer); > } >=20 > if (this.writer =3D=3D null) > { > this.writer =3D createWriter(); > } >=20 > this.socket =3D createSocket(); >=20 > this.reader.setSocket(socket); > this.readerThread =3D new Thread(reader, "ManagerReader"); > this.readerThread.setDaemon(true); > this.readerThread.start(); >=20 > this.writer.setSocket(socket); > } >=20 > protected SocketConnectionFacade createSocket() throws IOException > { > return new SocketConnectionFacadeImpl(asteriskServer.getHostnam= e(), > asteriskServer.getPort(), socketTimeout); > } >=20 > /** > * Returns <code>true</code> if there is a socket connection to the= > * asterisk server, <code>false</code> otherwise. > *=20 > * @return <code>true</code> if there is a socket connection to the= > * asterisk server, <code>false</code> otherwise. > */ > public synchronized boolean isConnected() > { > return socket !=3D null && socket.isConnected(); // JDK 1.4 > // return socket !=3D null; > } >=20 > /** > * Sends a {@link LogoffAction} and disconnects from the server. > */ > public synchronized void logoff() throws IOException, TimeoutExcept= ion > { > LogoffAction logoffAction; >=20 > // stop reconnecting when we got disconnected > this.keepAlive =3D false; >=20 > logoffAction =3D new LogoffAction(); >=20 > if (socket !=3D null) > { > sendAction(logoffAction); > disconnect(); > } > } >=20 > /** > * Closes the socket connection. > */ > private synchronized void disconnect() > { > if (this.socket !=3D null) > { > logger.info("Closing socket."); > try > { > this.socket.close(); > } > catch (IOException ex) > { > logger.warn("Unable to close socket: " + ex.getMessage(= )); > } > this.socket =3D null; > } > } >=20 > public ManagerResponse sendAction(ManagerAction action) throws IOEx= ception, > TimeoutException, IllegalArgumentException, IllegalStateExc= eption > { > return sendAction(action, defaultResponseTimeout); > } >=20 > public ManagerResponse sendAction(ManagerAction action, long timeou= t) > throws IOException, TimeoutException, IllegalArgumentExcept= ion, > IllegalStateException > { > ResponseHandlerResult result; > ManagerResponseHandler callbackHandler; >=20 > result =3D new ResponseHandlerResult(); > callbackHandler =3D new DefaultResponseHandler(result); >=20 > synchronized (result) > { > sendAction(action, callbackHandler); > try > { > result.wait(timeout); > } > catch (InterruptedException ex) > { > //TODO fix logging > System.err.println("Interrupted!"); > } > } > =20 > // still no response? > if (result.getResponse() =3D=3D null) > { > throw new TimeoutException("Timeout waiting for response to= " > + action.getAction()); > } >=20 > result.getResponse().setActionId(action.getActionId()); > return result.getResponse(); > } >=20 > public void sendAction(ManagerAction action, > ManagerResponseHandler callbackHandler) throws IOException,= > IllegalArgumentException, IllegalStateException > { > String internalActionId; >=20 > if (action =3D=3D null) > { > throw new IllegalArgumentException( > "Unable to send action: action is null."); > } >=20 > if (socket =3D=3D null) > { > throw new IllegalStateException("Unable to send " > + action.getAction() + " action: not connected."); > } >=20 > internalActionId =3D createInternalActionId(); >=20 > // if the callbackHandler is null the user is obviously not int= erested > // in the response, thats fine. > if (callbackHandler !=3D null) > { > synchronized (this.responseHandlers) > { > this.responseHandlers.put(internalActionId, callbackHan= dler); > } > } >=20 > action.setActionId(internalActionId); > writer.sendAction(action, internalActionId); > } >=20 > public ResponseEvents sendEventGeneratingAction(EventGeneratingActi= on action) > throws IOException, EventTimeoutException, > IllegalArgumentException, IllegalStateException > { > return sendEventGeneratingAction(action, defaultEventTimeout); > } >=20 > public ResponseEvents sendEventGeneratingAction( > EventGeneratingAction action, long timeout) throws IOExcept= ion, > EventTimeoutException, IllegalArgumentException, > IllegalStateException > { > ResponseEventsImpl responseEvents; > ResponseEventHandler responseEventHandler; > String internalActionId; >=20 > if (action =3D=3D null) > { > throw new IllegalArgumentException( > "Unable to send action: action is null."); > } > else if (action.getActionCompleteEventClass() =3D=3D null) > { > throw new IllegalArgumentException( > "Unable to send action: actionCompleteEventClass is= null."); > } > else if (!ResponseEvent.class.isAssignableFrom(action > .getActionCompleteEventClass())) > { > throw new IllegalArgumentException( > "Unable to send action: actionCompleteEventClass is= not a ResponseEvent."); > } >=20 > if (socket =3D=3D null) > { > throw new IllegalStateException("Unable to send " > + action.getAction() + " action: not connected."); > } >=20 > responseEvents =3D new ResponseEventsImpl(); > responseEventHandler =3D new ResponseEventHandler(responseEvent= s, action > .getActionCompleteEventClass()); >=20 > internalActionId =3D createInternalActionId(); >=20 > // register response handler... > synchronized (this.responseHandlers) > { > this.responseHandlers.put(internalActionId, responseEventHa= ndler); > } >=20 > // ...and event handler. > synchronized (this.responseEventHandlers) > { > this.responseEventHandlers.put(internalActionId, > responseEventHandler); > } >=20 > synchronized (responseEvents) > { > writer.sendAction(action, internalActionId); > try > { > responseEvents.wait(timeout); > } > catch (InterruptedException ex) > { > //TODO fix logging > System.err.println("Interrupted"); > } > } >=20 > // still no response or not all events received and timed out? > if ((responseEvents.getResponse() =3D=3D null || !responseEvent= s > .isComplete())) > { > // clean up > synchronized (this.responseEventHandlers) > { > this.responseEventHandlers.remove(internalActionId); > } >=20 > throw new EventTimeoutException( > "Timeout waiting for response or response events to= " > + action.getAction(), responseEvents); > } >=20 > // remove the event handler (note: the response handler is remo= ved > // automatically when the response is received) > synchronized (this.responseEventHandlers) > { > this.responseEventHandlers.remove(internalActionId); > } >=20 > return responseEvents; > } >=20 > /** > * Creates a new unique internal action id based on the hash code o= f this > * connection and a sequence. > *=20 > * @see Util#addInternalActionId(String, String) > * @see Util#getInternalActionId(String) > * @see Util#stripInternalActionId(String) > */ > private String createInternalActionId() > { > final StringBuffer sb; >=20 > sb =3D new StringBuffer(); > sb.append(this.hashCode()); > sb.append("_"); > sb.append(this.actionIdCount++); >=20 > return sb.toString(); > } >=20 > public void addEventHandler(final ManagerEventHandler eventHandler)= > { > synchronized (this.eventHandlers) > { > // only add it if its not already there > if (!this.eventHandlers.contains(eventHandler)) > { > this.eventHandlers.add(eventHandler); > } > } > } >=20 > public void removeEventHandler(final ManagerEventHandler eventHandl= er) > { > synchronized (this.eventHandlers) > { > if (this.eventHandlers.contains(eventHandler)) > { > this.eventHandlers.remove(eventHandler); > } > } > } >=20 > public String getProtocolIdentifier() > { > return this.protocolIdentifier; > } >=20 > public AsteriskServer getAsteriskServer() > { > return asteriskServer; > } >=20 > /* Implementation of Dispatcher: callbacks for ManagerReader */ >=20 > /** > * This method is called by the reader whenever a {@link ManagerRes= ponse} is > * received. The response is dispatched to the associated > * {@link ManagerResponseHandler}. > *=20 > * @param response the response received by the reader > * @see ManagerReader > */ > public void dispatchResponse(ManagerResponse response) > { > final String actionId; > String internalActionId; > ManagerResponseHandler responseHandler; >=20 > // shouldn't happen > if (response =3D=3D null) > { > logger.error("Unable to dispatch null response"); > return; > } >=20 > actionId =3D response.getActionId(); > internalActionId =3D null; > responseHandler =3D null; >=20 > if (actionId !=3D null) > { > internalActionId =3D Util.getInternalActionId(actionId); > response.setActionId(Util.stripInternalActionId(actionId));= > } >=20 > logger.debug("Dispatching response with internalActionId '" > + internalActionId + "':\n" + response); >=20 > if (internalActionId !=3D null) > { > synchronized (this.responseHandlers) > { > responseHandler =3D (ManagerResponseHandler) this.respo= nseHandlers > .get(internalActionId); > if (responseHandler !=3D null) > { > this.responseHandlers.remove(internalActionId); > } > else > { > // when using the async sendAction it's ok not to r= egister a > // callback so if we don't find a response handler = thats ok > logger.debug("No response handler registered for " > + "internalActionId '" + internalActionId += "'"); > } > } > } > else > { > logger.error("Unable to retrieve internalActionId from resp= onse: " > + "actionId '" + actionId + "':\n" + response); > } >=20 > if (responseHandler !=3D null) > { > try > { > responseHandler.handleResponse(response); > } > catch (RuntimeException e) > { > logger.warn("Unexpected exception in responseHandler " > + responseHandler.getClass().getName(), e); > } > } > } >=20 > /** > * This method is called by the reader whenever a ManagerEvent is r= eceived. > * The event is dispatched to all registered ManagerEventHandlers. > *=20 > * @param event the event received by the reader > * @see #addEventHandler(ManagerEventHandler) > * @see #removeEventHandler(ManagerEventHandler) > * @see ManagerReader > */ > public void dispatchEvent(ManagerEvent event) > { > // shouldn't happen > if (event =3D=3D null) > { > logger.error("Unable to dispatch null event"); > return; > } >=20 > logger.debug("Dispatching event:\n" + event.toString()); >=20 > // dispatch ResponseEvents to the appropriate responseEventHand= ler > if (event instanceof ResponseEvent) > { > ResponseEvent responseEvent; > String internalActionId; >=20 > responseEvent =3D (ResponseEvent) event; > internalActionId =3D responseEvent.getInternalActionId(); > if (internalActionId !=3D null) > { > synchronized (responseEventHandlers) > { > ManagerEventHandler eventHandler; >=20 > eventHandler =3D (ManagerEventHandler) responseEven= tHandlers > .get(internalActionId); > if (eventHandler !=3D null) > { > try > { > eventHandler.handleEvent(event); > } > catch (RuntimeException e) > { > logger.warn("Unexpected exception in eventH= andler " > + eventHandler.getClass().getName()= , e); > } > } > } > } > else > { > // ResponseEvent without internalActionId: > // this happens if the same event class is used as resp= onse event > // and as an event that is not triggered by a Manager c= ommand > // example: QueueMemberStatusEvent. > //logger.debug("ResponseEvent without " > // + "internalActionId:\n" + responseEvent); > } > } >=20 > // dispatch to eventHandlers registered by users > synchronized (eventHandlers) > { > for (ManagerEventHandler eventHandler : eventHandlers) > { > try > { > eventHandler.handleEvent(event); > } > catch (RuntimeException e) > { > logger.warn("Unexpected exception in eventHandler "= > + eventHandler.getClass().getName(), e); > } > } > } >=20 > // process special events > if (event instanceof ConnectEvent) > { > ConnectEvent connectEvent; > String protocolIdentifier; >=20 > connectEvent =3D (ConnectEvent) event; > protocolIdentifier =3D connectEvent.getProtocolIdentifier()= ; > setProtocolIdentifier(protocolIdentifier); > } > else if (event instanceof DisconnectEvent) > { > reconnect(); > } > } >=20 > /** > * This method is called when a {@link ConnectEvent} is received fr= om the > * reader. Having received a correct protocol identifier is the pre= codition > * for logging in. > *=20 > * @param protocolIdentifier the protocol version used by the Aster= isk > * server. > */ > private void setProtocolIdentifier(final String protocolIdentifier)= > { > logger.info("Connected via " + protocolIdentifier); >=20 > if (!"Asterisk Call Manager/1.0".equals(protocolIdentifier) && > !"Asterisk Call Manager/1.2".equals(protocolIdentifier)) > { > logger.warn("Unsupported protocol version '" + protocolIden= tifier > + "'. Use at your own risk."); > } >=20 > this.protocolIdentifier =3D protocolIdentifier; >=20 > } >=20 > /** > * Reconnects to the asterisk server when the connection is lost.<b= r> > * While keepAlive is <code>true</code> we will try to reconnect. > * Reconnection attempts will be stopped when the {@link #logoff()}= method > * is called or when the login after a successful reconnect results= in an > * {@link AuthenticationFailedException} suggesting that the manage= r > * credentials have changed and keepAliveAfterAuthenticationFailure= is not > * set.<br> > * This method is called when a {@link DisconnectEvent} is received= from the > * reader. > */ > private void reconnect() > { > int numTries; >=20 > // clean up at first > disconnect(); >=20 > // try to reconnect > numTries =3D 0; > while (this.keepAlive) > { > try > { > if (numTries < 10) > { > // try to reconnect quite fast for the firt 10 time= s > // this succeeds if the server has just been restar= ted > Thread.sleep(50); > } > else > { > // slow down after 10 unsuccessful attempts asuming= a > // shutdown of the server > Thread.sleep(5000); > } > } > catch (InterruptedException e1) > { > // it's ok to wake us > } >=20 > try > { > connect(); >=20 > try > { > login(); > logger.info("Successfully reconnected."); > // everything is ok again, so we leave > break; > } > catch (AuthenticationFailedException e1) > { > if (this.keepAliveAfterAuthenticationFailure) > { > logger.error("Unable to log in after reconnect.= "); > } > else > { > logger.error("Unable to log in after reconnect.= " > + "Giving up."); > this.keepAlive =3D false; > } > } > catch (TimeoutException e1) > { > // shouldn't happen > logger.error("TimeoutException while trying to log = in " > + "after reconnect."); > synchronized (this) > { > socket.close(); > } > } > } > catch (IOException e) > { > // server seems to be still down, just continue to atte= mpt > // reconnection > logger.warn("Exception while trying to reconnect: " > + e.getMessage()); > } > numTries++; > } > } >=20 > /* Helper classes */ >=20 > /** > * A simple data object to store a ManagerResult. > */ > private class ResponseHandlerResult implements Serializable > { > /** > * Serializable version identifier > */ > private static final long serialVersionUID =3D 7831097958568769= 220L; > private ManagerResponse response; >=20 > public ResponseHandlerResult() > { > } >=20 > public ManagerResponse getResponse() > { > return this.response; > } >=20 > public void setResponse(ManagerResponse response) > { > this.response =3D response; > } > } >=20 > /** > * A simple response handler that stores the received response in a= > * ResponseHandlerResult for further processing. > */ > private class DefaultResponseHandler > implements > ManagerResponseHandler, > Serializable > { > /** > * Serializable version identifier > */ > private static final long serialVersionUID =3D 2926598671855316= 803L; > private ResponseHandlerResult result; >=20 > /** > * Creates a new instance. > *=20 > * @param result the result to store the response in > */ > public DefaultResponseHandler(ResponseHandlerResult result) > { > this.result =3D result; > } >=20 > public void handleResponse(ManagerResponse response) > { > synchronized (result) > { > result.setResponse(response); > result.notify(); > } > } > } >=20 > /** > * A combinded event and response handler that adds received events= and the > * response to a ResponseEvents object. > */ > @SuppressWarnings("unchecked") > private class ResponseEventHandler > implements > ManagerEventHandler, > ManagerResponseHandler, > Serializable > { > /** > * Serializable version identifier > */ > private static final long serialVersionUID =3D 2926598671855316= 803L; > private final ResponseEventsImpl events; > private final Class actionCompleteEventClass; >=20 > /** > * Creates a new instance. > *=20 > * @param events the ResponseEventsImpl to store the events in > * @param actionCompleteEventClass the type of event that indic= ates that > * all events have been received > * @param thread the thread to interrupt when the > * actionCompleteEventClass has been received > */ > public ResponseEventHandler(ResponseEventsImpl events, > Class actionCompleteEventClass) > { > this.events =3D events; > this.actionCompleteEventClass =3D actionCompleteEventClass;= > } >=20 > public void handleEvent(ManagerEvent event) > { > synchronized (events) > { > // should always be a ResponseEvent, anyway... > if (event instanceof ResponseEvent) > { > ResponseEvent responseEvent; > =20 > responseEvent =3D (ResponseEvent) event; > events.addEvent(responseEvent); > } > =20 > // finished? > if (actionCompleteEventClass.isAssignableFrom(event.get= Class())) > { > events.setComplete(true); > // notify if action complete event and response hav= e been received > if (events.getResponse() !=3D null) > { > events.notify(); > } > } > } > } >=20 > public void handleResponse(ManagerResponse response) > { > synchronized (events) > { > events.setRepsonse(response); > if (response instanceof ManagerError) > { > events.setComplete(true); > } >=20 > // finished? > // notify if action complete event and response have be= en received > if (events.isComplete()) > { > events.notify(); > } > } > } > } > } >=20 >=20 > -----------------------------------------------------------------------= - >=20 > /* > * Copyright 2004-2006 by S. Brett Sutton. Commercial support is provid= ed by > * Asterisk I.T. http://www.asteriskit.com.au > *=20 > * The contents of this file are subject to a modified GPL Version 2 Li= cense or > * later version at your discretion. > *=20 > * The sole modification to the GPL is a limitation on use. > *=20 > * The limitation is that AsterFax (and its source components) may only= be used > * on a single Channel as defined in AsterFax.xml. The implications of = the > * limitation is that the free verions of AsterFax may only be used to = send or > * receive a single fax at a time. > *=20 > * Any copied or modified versions of the AsterFax source must retain t= his > * limitation. > *=20 > * If you wish to use multiple channels then you can purchase a commerc= ial > * license by emailing sa...@as... > *=20 > * Contributor(s): all the names of the contributors are added in the s= ource > * code where applicable. > */ > /** > * Responsible for submitting the fax to the asterix gateway for transm= ission > */ > package au.com.noojee.asterfax.outbound; >=20 > import java.io.IOException; > import java.net.ConnectException; > import java.util.Calendar; > import java.util.Date; > import java.util.HashMap; >=20 > import javax.activation.MimeTypeParseException; > import javax.mail.MessagingException; > import javax.mail.internet.InternetAddress; >=20 > import org.apache.commons.configuration.ConfigurationException; > import org.apache.log4j.Logger; > import org.asteriskjava.live.AsteriskChannel; > import org.asteriskjava.live.DefaultAsteriskManager; > import org.asteriskjava.manager.AuthenticationFailedException; > import org.asteriskjava.manager.ManagerConnection; > import org.asteriskjava.manager.ManagerConnectionFactory; > import org.asteriskjava.manager.ManagerEventHandler; > import org.asteriskjava.manager.TimeoutException; > import org.asteriskjava.manager.action.OriginateAction; > import org.asteriskjava.manager.event.DisconnectEvent; > import org.asteriskjava.manager.event.HangupEvent; > import org.asteriskjava.manager.event.ManagerEvent; > import org.asteriskjava.manager.event.OriginateFailureEvent; > import org.asteriskjava.manager.event.OriginateSuccessEvent; > import org.asteriskjava.manager.event.ReloadEvent; > import org.asteriskjava.manager.event.ShutdownEvent; > import org.asteriskjava.manager.response.ManagerError; > import org.asteriskjava.manager.response.ManagerResponse; >=20 > import au.com.noojee.asterfax.Configuration; > import au.com.noojee.asterfax.Responses; > import au.com.noojee.asterfax.SpanDSPError; > import au.com.noojee.asterfax.converter.ConversionException; >=20 > import com.lowagie.text.DocumentException; >=20 > public class SubmitFax implements ManagerEventHandler > { >=20 > static private Logger logger =3D Logger.getLogger(SubmitFax.class); > static Logger auditLogger =3D Logger.getLogger("Audit"); >=20 > static int asterFaxOriginateID =3D 1; >=20 > // If sent as an option to txfax then txfax will not actually send the= fax. > // It will just pretend to. This is usefull for testing asterfax witho= ut > // sending lost of faxes (and paying for it :) > static final String SIMULATE =3D "simulate"; >=20 > ManagerConnectionFactory factory =3D null; > private Channel channel =3D null; > Fax fax; > ManagerEvent response =3D null; > String cause =3D null; > private String actionID; > private String uniqueID; >=20 > public SubmitFax(Fax fax, Channel channel) > throws IOException, > ConfigurationException > { > this.fax =3D fax; > this.channel =3D channel; > factory =3D new ManagerConnectionFactory(Configuration.getInstance() > .getAsteriskHost(), Configuration.getInstance() > .getAsteriskUsername(), Configuration.getInstance() > .getAsteriskPassword()); >=20 > } >=20 > public void send() > throws IOException, > AuthenticationFailedException, > TimeoutException, > ConfigurationException, > MessagingException, > ClassNotFoundException, > InterruptedException, > ConversionException, > DocumentException, > IllegalArgumentException, > MimeTypeParseException > { > InternetAddress[] recipients =3D fax.getRecipients(); > for (InternetAddress address : recipients) > { >=20 > if (Fax.isPreview(address)) > { > Responses.sendPreview(fax, address); > } > else > { > boolean success =3D false; > int maxRetries =3D Configuration.getInstance().getMaxRetries(); > int retryCount =3D 0; > while (!success && retryCount < maxRetries) > { > if (retryCount !=3D 0) > logger.info("Retry (" + (retryCount + 1) > + ") transmission of: " + fax.toString()); > success =3D sendFaxAGI(address, retryCount =3D=3D maxRetries - 1);= > retryCount++; > } > } > } > } >=20 > /** > * TODO: create retry logic. > *=20 > * @param recipient > * @param reportError > * @throws ConfigurationException > * @throws MessagingException > * @throws ClassNotFoundException > * @throws IOException > * @throws InterruptedException > * @throws ConversionException > * @throws DocumentException > * @throws AuthenticationFailedException > * @throws TimeoutException > * @throws IllegalArgumentException > * @throws MimeTypeParseException > */ > synchronized boolean sendFaxAGI(InternetAddress recipient, > boolean reportError) > throws ConfigurationException, > MessagingException, > ClassNotFoundException, > IOException, > InterruptedException, > ConversionException, > DocumentException, > AuthenticationFailedException, > TimeoutException, > IllegalArgumentException, > MimeTypeParseException > { > boolean success =3D false; > ManagerConnection connection =3D null; > try > { > Date start =3D Calendar.getInstance().getTime(); > fax.setTransmissionStartTime(start); >=20 > // connect to Asterisk and log in > connection =3D getConnection(); > DefaultAsteriskManager dam =3D new DefaultAsteriskManager(connection= ); >=20 > try > { > dam.initialize(); > dam.setSkipQueues(true); > } > catch (ConnectException e) > { > throw new IllegalStateException( > "Connection to the asterisk manager api failed. Check that asteri= sk is up and configured to accept Manager API connections."); > } >=20 > OriginateAction originateAction; > ManagerResponse originateResponse; >=20 > originateAction =3D new OriginateAction(); > originateAction.setChannel(channel.getChannelName() + "/" > + Fax.getTelephoneNo(recipient)); > originateAction.setContext(channel.getContext()); > HashMap<String, String> variables =3D new HashMap<String, String>();= > // variables.put("LOCALHEADERINFO", Configuration.getInstance() > // .getCompanyName() + " " + fax.getSubject()); > Configuration config =3D Configuration.getInstance(); > variables.put("MaxRetries", "1"); > variables.put("RetryTime", new Integer(config.getRetryTime()) > .toString()); > variables > .put("WaitTime", new Long(config.getWaitTime()).toString()); >=20 > synchronized (SubmitFax.class) > { > variables.put("AsterFaxOriginateID", new Integer( > asterFaxOriginateID++).toString()); > } >=20 > // NEED to get the channels caller id (outbound cid). > AsteriskChannel astChannel =3D dam.getChannelByName(channel > .getChannelName()); > if (astChannel !=3D null) > variables > .put("REMOTESTATIONID", astChannel.getCallerIdNumber()); >=20 > String faxPath =3D fax.getTiffFile().getFile().getAbsolutePath(); > String data =3D faxPath + "|caller"; > if (config.isDebugTxFax()) > data +=3D "|debug"; >=20 > if (Configuration.getInstance().isDebugTxFaxSimulate()) > data +=3D "|" + SIMULATE; > originateAction.setApplication("txfax"); > originateAction.setData(data); > originateAction.setVariables(variables); > originateAction.setPriority(new Integer(config.getPriority())); > originateAction.setTimeout(new Long(config.getTimeOut())); > originateAction.setAsync(true); >=20 > logger.debug("Sending Action: Channel(" > + originateAction.getChannel() + ") Context(" > + originateAction.getContext() + ") Application (" > + originateAction.getApplication() + ") Data(" > + originateAction.getData() + ") Vars(" > + originateAction.getVariables() + ")"); >=20 > connection.addEventHandler(this); > // connection. > connection.registerUserEventClass(FaxTransmittedEvent.class); >=20 > originateResponse =3D connection.sendAction(originateAction, 30000);= > this.actionID =3D originateResponse.getActionId(); >=20 >=20 > // we need the "OriginateSuccess or OriginateFailure" events > logger.debug("Response:" + originateResponse + " resp:" > + originateResponse.getResponse() + "msg: " > + originateResponse.getMessage()); >=20 > if (originateResponse instanceof ManagerError) > { > if (reportError) > Responses.sendError((ManagerError) originateResponse, fax, > new InternetAddress[] > { > recipient > }); > } > else > { > // Wait for the hangup to notify us that the fax has > // been sent or an error occured > wait(); >=20 > assert response !=3D null : "response should never be null"; > if (response instanceof FaxTransmittedEvent) > { > FaxTransmittedEvent transmitted =3D (FaxTransmittedEvent) response= ; >=20 > if (transmitted.getExecResult() =3D=3D 0 > && transmitted.getTransmissionResult() =3D=3D 0) > { > logger.info("Fax transmitted successfully for: " > + fax.toString()); > success =3D true; > } > else > { > logger.warn("Transmission attempt failed. Will retry:" > + " Exec Result=3D" > + TXFaxError.valueOf(transmitted > .getExecResult()) > + " Transmission Result=3D" > + SpanDSPError.valueOf(transmitted > .getTransmissionResult()) > + fax.toString()); > if (reportError) > { > sendError(recipient, transmitted); > } > } > } > else > { > sendError(recipient, reportError); > } > } >=20 > fax.cleanUp(); >=20 > } > catch (Throwable e) > { >=20 > logger.error(e.getMessage(), e); >=20 > if (fax !=3D null) > { > try > { > Responses.sendError(e, fax, new InternetAddress[] > { > recipient > }); > } > catch (Throwable e1) > { > logger.error("Error attempting to send error response", e1); > } > } > } > finally > { >=20 > connection.removeEventHandler(this); >=20 > Date end =3D Calendar.getInstance().getTime(); > fax.setTransmissionEndTime(end); >=20 > if (success) > { > auditLogger.info("Success: " + fax.toString(recipient)); > Responses.sendArchive(fax, recipient); > Responses.sendReceipt(fax, recipient); > } > else > auditLogger.info("Failed: " + fax.toString(recipient)); >=20 > if (connection !=3D null) > connection.logoff(); > } >=20 > return success; > } >=20 > public synchronized void handleEvent(ManagerEvent event) > { > if (event instanceof OriginateSuccessEvent) > { > OriginateSuccessEvent success =3D (OriginateSuccessEvent) event; > if (this.actionID.compareToIgnoreCase(success.getActionId()) =3D=3D = 0) > { > logger > .debug("OriginateSuccessEvent received for channel(" > + success.getChannel() > + ") with the following cause: " > + success.toString()); > this.uniqueID =3D success.getUniqueId(); > } > } > else if (event instanceof OriginateFailureEvent) > { > OriginateFailureEvent failure =3D (OriginateFailureEvent) event; > if (this.actionID.compareToIgnoreCase(failure.getActionId()) =3D=3D = 0) > { > logger.debug("OriginateFailureEvent received for channel(" > + failure.getChannel() + ") with the following cause: " > + failure.toString()); >=20 > if (response =3D=3D null) > logger > .warn("Originate Falled for call to " + failure.getChannel()); > setResponse(failure); > notify(); > } > } >=20 > else if (event instanceof HangupEvent) > { > HangupEvent hangup =3D (HangupEvent) event; > if (isOurChannel(hangup.getUniqueId())) > { > logger.debug("HangupEvent received for channel(" > + hangup.getChannel() + ") with the following cause: " > + hangup.getCause() + " " + hangup.getCauseTxt()); >=20 > if (response =3D=3D null) > logger > .error("Hangup received before FaxTransmittedEvent. Please check= that you have patched TxFax."); > setResponse(hangup); > notify(); > } > } > else if (event instanceof DisconnectEvent) > { > cause =3D "AsterFax lost its connection to Asterisk."; > logger > .debug("Received unexpected DisconnectEvent while waiting for fax = hangup."); > setResponse(event); > notify(); > } > else if (event instanceof ShutdownEvent) > { > cause =3D "Asterisk Shutting down."; > logger > .warn("Received unexpected ShutdownEvent while waiting for fax han= gup."); > setResponse(event); > notify(); > } > else if (event instanceof ReloadEvent) > { > cause =3D "Asterisk Reloadinging."; > logger > .warn("Received unexpected ReloadEvent while waiting for fax hangu= p."); > setResponse(event); > notify(); > } > else if (event instanceof FaxTransmittedEvent) > { >=20 > FaxTransmittedEvent a =3D (FaxTransmittedEvent) event; > if (isOurChannel(a.getUniqueId())) > { > logger.debug("Received FaxTransmittedEvent. ExecResult=3D" > + a.getExecResult() + " TransmissionResult=3D" > + a.getTransmissionResult() + " RemoteStationID=3D" > + a.getRemoteStationID() + " Pages Transferred=3D" > + a.getPagesTransferred()); > setResponse(a); > notify(); > } > } > // else > // { > // ignore these other events. > // logger > // .debug("Received unexpected Event while waiting for fax hangup. > // event=3D" > // + event.toString()); > // } > } >=20 > private void setResponse(ManagerEvent event) > { > if (response =3D=3D null) > { > response =3D event; > } > else > { > logger.debug("Event recieved when response already set: " > + event.toString()); > } >=20 > } >=20 > boolean isOurChannel(String uniqueID) > { > assert uniqueID !=3D null : "Unique id not passed!"; > assert this.uniqueID !=3D null : "Unique id not set!"; > return (uniqueID.toLowerCase().compareToIgnore... [truncated message content] |
From: Brett S. <bs...@no...> - 2006-03-16 12:44:09
|
I've been trying to determine a reliable method for matching events to an originate. I've experimented with the DefaultManagerConnection Call method, but I'm not convinced its reliable (in fact I'm pretty certain it isn't). As such I've developed a patch for the DefaultMangerConnection sendAction method. The patch basically sets the ActionID of the response object, currently it is left as null. By setting the actionid, and using the Async mode of sendAction which generates an OriginateSuccessEvent (or failure) I have been able to retrieve the uniqueid associated with the originate and then use that to match subsequent events. Please find the attached update to DefaultManagerConnection. I have also submitted a sample class from AsterFax which demonstrates the technique described. I believe the patch is non-invasive. Regards, Brett. |
From: Ron S. <rse...@ha...> - 2006-03-16 04:21:55
|
> > Using the asterisk-java I can connect to asterisk but i have no idea how > to dial for anyone. > Asterisk-java is for controlling asterisk, not for actually being a phone. -Ron |
From: Jon H. <jo...@as...> - 2006-03-15 20:12:13
|
Fabio, If you're interested in making a softphone that can use asterisk-java, you'll first want to read up on sip, iax, or both. While sending requests to call people via iax or sip is what most people do, read up on the asterisk manager. With it, asterisk-java can send originate requests to call people, and also you'll be able to bridge people elsewhere mid-call using the asterisk manager and asterisk-java. Hopefully after you read up on sip and/or iax, it will help you understand how you should go about creating a softphone. -Jon Fabio Esposito wrote: > Hello, > > I'm want to make a softphone with asterisk-java. Is this possible? > Reading the documentation asterisk-java I can't understand if he is > only for manager the server or to use as client (note: i'm brazilian > and my english isn't so good) > > I have difficult to understand what is the channel, context and the > extension for example. > > Using the asterisk-java I can connect to asterisk but i have no idea > how to dial for anyone. > > Thanks > Fábio Espósito > > > > > > > > ------------------------------------------------------- > This SF.Net email is sponsored by xPML, a groundbreaking scripting > language > that extends applications into web and mobile media. Attend the live > webcast > and join the prime developer group breaking into this new coding > territory! > http://sel.as-us.falkag.net/sel?cmd=k&kid0944&bid$1720&dat1642 > _______________________________________________ > Asterisk-java-users mailing list > Ast...@li... > https://lists.sourceforge.net/lists/listinfo/asterisk-java-users |
From: Fabio E. <fab...@gm...> - 2006-03-15 18:48:07
|
Hello, I'm want to make a softphone with asterisk-java. Is this possible? Reading the documentation asterisk-java I can't understand if he is only=20 for manager the server or to use as client (note: i'm brazilian and my=20 english isn't so good) I have difficult to understand what is the channel, context and the=20 extension for example. Using the asterisk-java I can connect to asterisk but i have no idea how=20 to dial for anyone. Thanks F=E1bio Esp=F3sito |
From: Peter H. <pe...@ra...> - 2006-03-15 13:37:28
|
Hello! A notification that I have finished another example application (AstConnection) that shows how to use the manager connection in asterisk-java (version 0.2). This application is kept extremely simple (one class with one main method). I would appreciate feedback / suggestions of improvements, especially concerning the documentation. Read-only access to the application is on http://svn.reucon.net/repos/asterisk-java-examples/trunk/simple-ast-connection/ and the source file is in sub folder /org/rww/asterisk/AstConnection.java Documentation can be found in the sub folder /doc Peter Hoppe -- dyslexics of the world - untie ! |
From: Jan du T. <jan...@de...> - 2006-03-15 09:14:50
|
Sweet, works fine. Thank you. Stefan Reuter wrote: >Hi Jan, > >Jan du Toit wrote: > > >>In the extensions.conf, I have an extension setup for Bob as follows : >> exten => 5005,1,Dial(SIP/Bob,20,tr) >> >>This extension will always be known to the system. >>Is their a way to successfully origante the call for Bob to connect to >>the MeetMe room, using the 5005 extension and no channel name. >> >> > >you can use a "Local" channel for that. >Example: Local/5005@sip-context > >=Stefan > > > |
From: Stefan R. <sr...@re...> - 2006-03-15 09:05:46
|
Hi Jan, Jan du Toit wrote: > In the extensions.conf, I have an extension setup for Bob as follows : > exten =3D> 5005,1,Dial(SIP/Bob,20,tr) >=20 > This extension will always be known to the system. > Is their a way to successfully origante the call for Bob to connect to > the MeetMe room, using the 5005 extension and no channel name. you can use a "Local" channel for that. Example: Local/5005@sip-context =3DStefan --=20 reuter network consulting Neusser Str. 110 50760 K=F6ln Germany Telefon: +49 221 1305699-0 Telefax: +49 221 1305699-90 E-Mail: sr...@re... |
From: Jan du T. <jan...@de...> - 2006-03-15 07:15:12
|
Hi. Currently I am using the Originate class to connect into a MeetMe room, setting the application and data of the originate accordingly. For the Originate action to work you need to supply the channel on which to connect the outgoing call to. For example I have a sip user called Bob, who wants to connect to the meetme room. So I configure the Origanate with "SIP/Bob" and it works. The problem is the program might not always know the correct channel name... In the extensions.conf, I have an extension setup for Bob as follows : exten => 5005,1,Dial(SIP/Bob,20,tr) This extension will always be known to the system. Is their a way to successfully origante the call for Bob to connect to the MeetMe room, using the 5005 extension and no channel name. Thanks in advance. |
From: Peter H. <pe...@ra...> - 2006-03-15 02:53:57
|
Hello! This is just a notification that I have finished an example application (ast-console) that shows how to use the manager connection in asterisk-java (version 0.2). I would appreciate feedback / suggestions of improvements, especially concerning the documentation. Read-only access to the application is on http://svn.reucon.net/repos/asterisk-java-examples/trunk/ast-console/ Many thanks for the excellent asterisk-java framework! Peter Hoppe -- dyslexics of the world - untie ! |
From: Ron S. <rse...@gm...> - 2006-03-14 06:16:12
|
On 3/13/06, Stefan Reuter <sr...@re...> wrote: > Hey Ron, > > thanks for reporting this issue. > It is caused by the QueueMemberStatusEvent being used in two different > ways by Asterisk: as response to a QueueStatusAction and as a "normal" > event in the situation u described. I wasn't aware of that when i coded i= t. > You can silently ignore that error (it has no real side effects) or > start using 0.3-SNAPSHOT - there it is fixed. > URL: http://www.asteriskjava.org/0.3-SNAPSHOT/ > http://maven.reucon.com/maven2/org/asteriskjava/asterisk-java/0.3-SNAPSHO= T/ > > =3DStefan Thanks! I've updated to the snapshot and all is working well... lot's of refactored packages in 0.3 eh? Great work Stefan. -Ron |
From: Stefan R. <sr...@re...> - 2006-03-13 18:13:08
|
Hey Ron, thanks for reporting this issue. It is caused by the QueueMemberStatusEvent being used in two different ways by Asterisk: as response to a QueueStatusAction and as a "normal" event in the situation u described. I wasn't aware of that when i coded i= t. You can silently ignore that error (it has no real side effects) or start using 0.3-SNAPSHOT - there it is fixed. URL: http://www.asteriskjava.org/0.3-SNAPSHOT/ http://maven.reucon.com/maven2/org/asteriskjava/asterisk-java/0.3-SNAPSHO= T/ =3DStefan --=20 reuter network consulting Neusser Str. 110 50760 K=F6ln Germany Telefon: +49 221 1305699-0 Telefax: +49 221 1305699-90 E-Mail: sr...@re... Jabber: sr...@ja... |
From: g f <gf...@gm...> - 2006-03-13 18:11:27
|
Stefan, Looking at the HelloAgi example, the actual service() method is called when exten 1300 is dialed(if I follow the *-Java tutorial). I am unsure how to call the dynamic meetme script example that you gave me (below). Could you give me an idea of how to accomplish this? Thanks!!! On 3/9/06, Stefan Reuter <sr...@re...> wrote: > > no just put the exten =3D> s,n,MeetMe(${CONF}|dTMps) (or similar) into > extensions.conf and use setContext/Extension/Priority in your AGI that > way it just quits after verifying the pin. > Example: > > extensions.conf: > > [conf] > exten =3D> _X.,1,MeetMe(${EXTEN}|dTMps) > > and: > > public class AgiCommand extends BaseAGIScript > { > public void service(AGIRequest request, AGIChannel channel) > throws AGIException > { > ... > if (verifyPin()) > { > setContext("conf"); > setExtension(confNumber); > setPriority(1); > } > else > { > streamFile("invalid-pin"); > hangup(); > } > } > } > > =3DStefan > > -- > reuter network consulting > Neusser Str. 110 > 50760 K=F6ln > Germany > Telefon: +49 221 1305699-0 > Telefax: +49 221 1305699-90 > E-Mail: sr...@re... > Jabber: sr...@ja... > > > > |
From: Ron S. <rse...@gm...> - 2006-03-13 16:58:23
|
Hi, I'm successfully using the asterisk-java manager interface to listen for events. Everything works great. There seems to be an underlying problem, however, with an event generated by Asterisk that generates this error: Mar 13, 2006 9:50:07 AM net.sf.asterisk.util.impl.JavaLoggingLog error SEVERE: Unable to handle ResponseEvent without internalActionId: net.sf.asterisk.manager.event.QueueMemberStatusEvent: dateReceived=3DMon Mar 13 09:50:07 CST 2006; privilege=3Dagent,all; systemHashcode=3D7668057 It definitely is related to QueueMembers, as it is in direct correlation to the number of agents listed in the queue (regardless of them being logged in or out). If I have 4 agents, I'll receive the error 4 times in a row. Also, I tried enabling and disabling eventwhencalled=3Dyes eventmemberstatusoff=3Dno within the queue, but the event is still being seen by asterisk (I restarted the Asterisk service just to make sure all changes took effect as well). The event is triggered when a call is placed to the queue. I'm running Asterisk 1.2.5, so my thought is maybe there's a new event that is now included w/ asterisk? TIA! -Ron |
From: g f <gf...@gm...> - 2006-03-10 15:07:03
|
Thanks Stefan!! Glad you're back!! On 3/9/06, Stefan Reuter <sr...@re...> wrote: > > no just put the exten =3D> s,n,MeetMe(${CONF}|dTMps) (or similar) into > extensions.conf and use setContext/Extension/Priority in your AGI that > way it just quits after verifying the pin. > Example: > > extensions.conf: > > [conf] > exten =3D> _X.,1,MeetMe(${EXTEN}|dTMps) > > and: > > public class AgiCommand extends BaseAGIScript > { > public void service(AGIRequest request, AGIChannel channel) > throws AGIException > { > ... > if (verifyPin()) > { > setContext("conf"); > setExtension(confNumber); > setPriority(1); > } > else > { > streamFile("invalid-pin"); > hangup(); > } > } > } > > =3DStefan > > -- > reuter network consulting > Neusser Str. 110 > 50760 K=F6ln > Germany > Telefon: +49 221 1305699-0 > Telefax: +49 221 1305699-90 > E-Mail: sr...@re... > Jabber: sr...@ja... > > > > |
From: Stefan R. <sr...@re...> - 2006-03-10 01:53:22
|
Hi Brett, > 1. txfax returns a value of -1 but the return from the call to > BaseAGIScript.exec("txfax", data) returns a value of 0. you dont have access to the return value through AGI afaik. > 2. I have modified app_txfax.c to set a channel variable to indicate > indicate the actual reason for the failure. When I attempt to retrieve > the channel value null is returned: yeah thats the way to go. (and with Asterisk 1.2 return values are deprected in favor of channel variables anyway) I dont see why "FAX_RESULT" isnt set correctly and "FAX_DEBUG" seems to be ok... did you do anything different regarding those two variables? Are you sure your code in app_txfax.c is executed? Maybe some debug logging statements help there. =3DStefan --=20 reuter network consulting Neusser Str. 110 50760 K=F6ln Germany Telefon: +49 221 1305699-0 Telefax: +49 221 1305699-90 E-Mail: sr...@re... Jabber: sr...@ja... |
From: Stefan R. <sr...@re...> - 2006-03-10 01:40:23
|
no just put the exten =3D> s,n,MeetMe(${CONF}|dTMps) (or similar) into extensions.conf and use setContext/Extension/Priority in your AGI that way it just quits after verifying the pin. Example: extensions.conf: [conf] exten =3D> _X.,1,MeetMe(${EXTEN}|dTMps) and: public class AgiCommand extends BaseAGIScript { public void service(AGIRequest request, AGIChannel channel) throws AGIException { ... if (verifyPin()) { setContext("conf"); setExtension(confNumber); setPriority(1); } else { streamFile("invalid-pin"); hangup(); } } } =3DStefan --=20 reuter network consulting Neusser Str. 110 50760 K=F6ln Germany Telefon: +49 221 1305699-0 Telefax: +49 221 1305699-90 E-Mail: sr...@re... Jabber: sr...@ja... |
From: g f <gf...@gm...> - 2006-03-09 17:03:28
|
My network is down right now so I cant run anything against my asterisk box but is this kind of the jist of what you do (aside from the validation) public class AgiCommand extends BaseAGIScript { public void service(AGIRequest request, AGIChannel channel) throws AGIException { exec("exten =3D> s,n,MeetMe(${CONF}|dTMps)"); } } ??? Thanks again. On 3/9/06, Chris Howard <ch...@as...> wrote: > > What we do is get the pin in the agi, query the database to validate the > pin. Set the conference number for the dialplan to use and call: > > exten =3D> s,n,MeetMe(${CONF}|dTMps) > -----Original Message----- > *From:* ast...@li... [mailto: > ast...@li...] *On Behalf Of *g f > *Sent:* Wednesday, March 08, 2006 11:46 AM > *To:* ast...@li... > *Subject:* Re: [Asterisk-java-users] dynamically adding new conference > rooms > > I found the following, but I was just assuming that this was a line that > was added in the extensions.conf file and not a CLI: > > Dynamic conference room, user must input room number to be created: > exten =3D> 9999,1, Wait(1) > exten =3D> 9999,2,MeetMe(|Md) ; NOTE: If you add the option 'e', * w= ill choose room # for you > > ;Change the 'd' option to 'D' if you want to have a pin number for the c= onference > > > Chris, > is this what you use? > > Thanks in advance!! > > > On 3/7/06, Chris Howard <ch...@as...> wrote: > > > > > > On Mar 7, 2006, at 5:22 PM, Stefan Reuter wrote: > > > > > Hi, > > > > > > g f wrote: > > >> I was interested in allowing users the ability to create new > > >> conference > > >> rooms. > > >> Is there any * to Java classes that will accomplish this? > > >> I looked at MeetmeEvents but found nothing that looked promising. > > >> Any help is appreciated.. > > > > > > no there is currently no way to accomplish this through the Manager > > > API > > > that I am aware of. > > > Do you know if its possible through CLI? (I had a quick look but didn= t > > > find anything either) > > > > You probably want to use dynamic meetme conferences and manage them > > with an external database and not try to add a static conference. We > > have built a conferencing system using this approach using AGI for > > authentication and it works great. > > > > Chris > > > > > > > > > > ------------------------------------------------------- > > This SF.Net email is sponsored by xPML, a groundbreaking scripting > > language > > that extends applications into web and mobile media. Attend the live > > webcast > > and join the prime developer group breaking into this new coding > > territory! > > http://sel.as-us.falkag.net/sel?cmd=3Dlnk&kid=3D110944&bid=3D241720&dat= =3D121642 > > _______________________________________________ > > Asterisk-java-users mailing list > > Ast...@li... > > https://lists.sourceforge.net/lists/listinfo/asterisk-java-users > > > > |
From: Chris H. <ch...@as...> - 2006-03-09 15:04:12
|
What we do is get the pin in the agi, query the database to validate the pin. Set the conference number for the dialplan to use and call: exten => s,n,MeetMe(${CONF}|dTMps) -----Original Message----- From: ast...@li... [mailto:ast...@li...] On Behalf Of g f Sent: Wednesday, March 08, 2006 11:46 AM To: ast...@li... Subject: Re: [Asterisk-java-users] dynamically adding new conference rooms I found the following, but I was just assuming that this was a line that was added in the extensions.conf file and not a CLI: Dynamic conference room, user must input room number to be created: exten => 9999,1, Wait(1) exten => 9999,2,MeetMe(|Md) ; NOTE: If you add the option 'e', * will choose room # for you ;Change the 'd' option to 'D' if you want to have a pin number for the conference Chris, is this what you use? Thanks in advance!! On 3/7/06, Chris Howard <ch...@as...> wrote: On Mar 7, 2006, at 5:22 PM, Stefan Reuter wrote: > Hi, > > g f wrote: >> I was interested in allowing users the ability to create new >> conference >> rooms. >> Is there any * to Java classes that will accomplish this? >> I looked at MeetmeEvents but found nothing that looked promising. >> Any help is appreciated.. > > no there is currently no way to accomplish this through the Manager > API > that I am aware of. > Do you know if its possible through CLI? (I had a quick look but didnt > find anything either) You probably want to use dynamic meetme conferences and manage them with an external database and not try to add a static conference. We have built a conferencing system using this approach using AGI for authentication and it works great. Chris ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk <http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=12164 2> &kid=110944&bid=241720&dat=121642 _______________________________________________ Asterisk-java-users mailing list Ast...@li... https://lists.sourceforge.net/lists/listinfo/asterisk-java-users |
From: Brett S. <bs...@no...> - 2006-03-09 11:56:07
|
Help.................. I've written a Fast AGI application which calls BaseAGIScript.exec("txfax", data); The application txfax is called successfully. I have two problems. 1. txfax returns a value of -1 but the return from the call to BaseAGIScript.exec("txfax", data) returns a value of 0. 2. I have modified app_txfax.c to set a channel variable to indicate indicate the actual reason for the failure. When I attempt to retrieve the channel value null is returned: e.g. <code> String resultVar = getVariable(SubmitFax.FAX_RESULT); </code> where SubmitFax.FAX_RESULT is defined as: <code> public static final String FAX_RESULT = "FAX_RESULT"; </code> The relevant txfax code uses: <code> ast_log(LOG_DEBUG, "==============================================================================\n"); ast_log(LOG_DEBUG, "Fax send not successful - result %d.\n", result); ast_log(LOG_DEBUG, "==============================================================================\n"); char varResult[64]; sprintf(varResult, "%d", result); pbx_builtin_setvar_helper(chan, "FAX_RESULT", varResult); <code> The last lines of the txfax_exec method is: <code> ast_log(LOG_DEBUG, "returning=%d\n", res); return res; } </code> The log file displays the following: Mar 9 22:41:44 DEBUG[18786] app_txfax.c: ============================================================================== Mar 9 22:41:44 DEBUG[18786] app_txfax.c: Fax send not successful - result 3. Mar 9 22:41:44 DEBUG[18786] app_txfax.c: ============================================================================== Mar 9 22:41:44 DEBUG[18786] app_txfax.c: returning=-1 Mar 9 22:41:44 VERBOSE[18786] logger.c: -- AGI Script agi://192.168.0.3/CallTxFax.agi?channel=ZAP/g0 completed, returning 0 And if I run ngrep I see the following: ngrep -d eth0:1 -s 4000 port 4573 interface: eth0:1 (192.168.0.0/255.255.255.0) filter: ip and ( port 4573 ) #### T 192.168.0.4:33154 -> 192.168.0.3:4573 [AP] agi_network: yes. ## T 192.168.0.4:33154 -> 192.168.0.3:4573 [AP] agi_network_script: CallTxFax.agi?channel=ZAP/g0.agi_request: agi://192.168 .0.3/CallTxFax.agi?channel=ZAP/g0.agi_channel: Zap/3-1.agi_language: en.agi _type: Zap.agi_uniqueid: 1141904464.71.agi_callerid: unknown.agi_calleridna me: unknown.agi_callingpres: 0.agi_callingani2: 0.agi_callington: 0.agi_cal lingtns: 0.agi_dnid: unknown.agi_rdnis: unknown.agi_context: incoming.agi_e xtension: s.agi_priority: 1.agi_enhanced: 0.0.agi_accountcode: .. # T 192.168.0.3:4573 -> 192.168.0.4:33154 [AP] GET VARIABLE "FAX_PATH". ## T 192.168.0.4:33154 -> 192.168.0.3:4573 [AP] 200 result=1 (C:\usr\lib\asterfax\outbox\QWWWxx28423.tif). # T 192.168.0.3:4573 -> 192.168.0.4:33154 [AP] GET VARIABLE "FAX_DEBUG". # T 192.168.0.4:33154 -> 192.168.0.3:4573 [AP] 200 result=1 (DEBUG). # T 192.168.0.3:4573 -> 192.168.0.4:33154 [AP] EXEC "txfax" "C:\usr\lib\asterfax\outbox\QWWWxx28423.tif|caller|debug". ## T 192.168.0.4:33154 -> 192.168.0.3:4573 [AP] 200 result=0. # T 192.168.0.3:4573 -> 192.168.0.4:33154 [AP] GET VARIABLE "FAX_RESULT". ## T 192.168.0.4:33154 -> 192.168.0.3:4573 [AP] 200 result=0. ### |
From: Stefan R. <sr...@re...> - 2006-03-08 22:26:38
|
Jason Wolfe wrote: > as it turns out... I can't concatenate String variables in java on this= > machine!? (weird I know) This thing in a main runs on my test and > devolepment machines fine, then get's to the production machine as a se= rvice > and fails... even in a main) what JDK are you running on that machine? a sun one or some of the "free" ones like kaffee that sometimes come shipped with linux distros? try a java -version You probably want to make sure you are actually running a recent sun (or bea jrockit) jdk there. =3DStefan --=20 reuter network consulting Neusser Str. 110 50760 K=F6ln Germany Telefon: +49 221 1305699-0 Telefax: +49 221 1305699-90 E-Mail: sr...@re... Jabber: sr...@ja... |
From: Forte, G. \(GFORTE\) <gf...@ar...> - 2006-03-08 21:56:16
|
Jason, this is a shot in the dark but perhaps try a StringBuffer instead of a = String as it is supposed to be more efficient at handling = concatenations. Perhaps this will "fool" your production machine into = processing your code correctly. =20 StringBuffer sb =3D new StringBuffer("jason"); sb.append("clickforacall"); sb.append("com"); =20 Graham =20 =20 |
From: Jason W. <jas...@be...> - 2006-03-08 21:29:11
|
thank you, as it turns out... I can't concatenate String variables in java on this machine!? (weird I know) This thing in a main runs on my test and devolepment machines fine, then get's to the production machine as a service and fails... even in a main) As this is now a Java/Linux problem I'll be off topic if I proceed, but any ideas would be very helpful. I looked in var/log/messages and var/log/secure and found nothing. I was running the SElinux and turned that off, the problem may have started when I did this. jason -----Original Message----- From: ast...@li... [mailto:ast...@li...]On Behalf Of Stefan Reuter Sent: Wednesday, March 08, 2006 3:54 PM To: ast...@li... Subject: Re: [Asterisk-java-users] Is this a bug? Jason Wolfe wrote: > The following code hangs evertime on my machine. It's because of the > concatenation; if I take it out (dmail=email1+email2+email3;) then it works > fine... How can I further nail down the problem? I get 'INFO: Received > Connection.' and nothing else... subsequent to failure, calls to this script > show 'SEVERE: no script configured' error I ran your script here with A-J 0.2 with a ResourceBundleMappingStrategy and besides the fact that it doesnt do anything it run well - even multiple times. =Stefan -- reuter network consulting Neusser Str. 110 50760 Köln Germany Telefon: +49 221 1305699-0 Telefax: +49 221 1305699-90 E-Mail: sr...@re... Jabber: sr...@ja... |
From: Stefan R. <sr...@re...> - 2006-03-08 20:54:17
|
Jason Wolfe wrote: > The following code hangs evertime on my machine. It's because of the > concatenation; if I take it out (dmail=3Demail1+email2+email3;) then it= works > fine... How can I further nail down the problem? I get 'INFO: Received > Connection.' and nothing else... subsequent to failure, calls to this s= cript > show 'SEVERE: no script configured' error I ran your script here with A-J 0.2 with a ResourceBundleMappingStrategy and besides the fact that it doesnt do anything it run well - even multiple times. =3DStefan --=20 reuter network consulting Neusser Str. 110 50760 K=F6ln Germany Telefon: +49 221 1305699-0 Telefax: +49 221 1305699-90 E-Mail: sr...@re... Jabber: sr...@ja... |
From: g f <gf...@gm...> - 2006-03-08 17:45:35
|
I found the following, but I was just assuming that this was a line that was added in the extensions.conf file and not a CLI: Dynamic conference room, user must input room number to be created: exten =3D> 9999,1, Wait(1) exten =3D> 9999,2,MeetMe(|Md) ; NOTE: If you add the option 'e', * will choose room # for you ;Change the 'd' option to 'D' if you want to have a pin number for the conference Chris, is this what you use? Thanks in advance!! On 3/7/06, Chris Howard <ch...@as...> wrote: > > > On Mar 7, 2006, at 5:22 PM, Stefan Reuter wrote: > > > Hi, > > > > g f wrote: > >> I was interested in allowing users the ability to create new > >> conference > >> rooms. > >> Is there any * to Java classes that will accomplish this? > >> I looked at MeetmeEvents but found nothing that looked promising. > >> Any help is appreciated.. > > > > no there is currently no way to accomplish this through the Manager > > API > > that I am aware of. > > Do you know if its possible through CLI? (I had a quick look but didnt > > find anything either) > > You probably want to use dynamic meetme conferences and manage them > with an external database and not try to add a static conference. We > have built a conferencing system using this approach using AGI for > authentication and it works great. > > Chris > > > > > ------------------------------------------------------- > This SF.Net email is sponsored by xPML, a groundbreaking scripting > language > that extends applications into web and mobile media. Attend the live > webcast > and join the prime developer group breaking into this new coding > territory! > http://sel.as-us.falkag.net/sel?cmd=3Dlnk&kid=3D110944&bid=3D241720&dat= =3D121642 > _______________________________________________ > Asterisk-java-users mailing list > Ast...@li... > https://lists.sourceforge.net/lists/listinfo/asterisk-java-users > |