[Asterisk-java-cvs] CVS: asterisk-java/src/java/net/sf/asterisk/manager Call.java,NONE,1.1 Originate
Brought to you by:
srt
Update of /cvsroot/asterisk-java/asterisk-java/src/java/net/sf/asterisk/manager In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30218/src/java/net/sf/asterisk/manager Modified Files: DefaultAsteriskManager.java AsteriskManager.java MultiAsterisksManager.java Added Files: Call.java Originate.java Log Message: Included Ben Hencke's patch for the "UniqueId and originate command" problem. --- NEW FILE: Call.java --- /* * Copyright 2004-2005 Stefan Reuter * * Copyright 2005 Ben Hencke * * 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 implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.sf.asterisk.manager; import java.util.*; /** * @author Ben Hencke */ public class Call { private String uniqueId; private Integer reason; private Channel channel; private Date startTime; private Date endTime; public Call() { startTime = new Date(); } public String getUniqueId() { return uniqueId; } public void setUniqueId(String uniqueId) { this.uniqueId = uniqueId; } public Channel getChannel() { return channel; } public void setChannel(Channel channel) { this.channel = channel; } public Integer getReason() { return reason; } public void setReason(Integer reason) { this.reason = reason; } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } /** * @return The duration of the call in milliseconds. If the call is has not * ended, the duration so far is calculated. */ public long calcDuration() { Date compTime; if (endTime != null) { compTime = endTime; } else { compTime = new Date(); } return compTime.getTime() - startTime.getTime(); } public String toString() { StringBuffer sb; sb = new StringBuffer(getClass().getName() + ": "); sb.append("uniqueId=" + getUniqueId() + "; "); sb.append("reason=" + getReason() + "; "); sb.append("startTime=" + getStartTime() + "; "); sb.append("endTime=" + getEndTime() + "; "); sb.append("systemHashcode=" + System.identityHashCode(this)); return sb.toString(); } } --- NEW FILE: Originate.java --- /* * Copyright 2004-2005 Stefan Reuter * * Copyright 2005 Ben Hencke * * * 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 implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.sf.asterisk.manager; import java.util.*; /** * @author Ben Hencke */ public class Originate { private String channel; private String exten; private String context; private Integer priority; private Integer timeout; private String callerId; private Map variables = new HashMap(); private String account; private String application; private String data; /** * Returns the account code to use for the originated call. */ public String getAccount() { return account; } /** * Sets the account code to use for the originated call.<br> * The account code is included in the call detail record generated for this * call and will be used for billing. */ public void setAccount(String account) { this.account = account; } /** * Returns the caller id to set on the outgoing channel. */ public String getCallerId() { return callerId; } /** * Sets the caller id to set on the outgoing channel. */ public void setCallerId(String callerId) { this.callerId = callerId; } /** * Returns the name of the channel to connect to the outgoing call. */ public String getChannel() { return channel; } /** * Sets the name of the channel to connect to the outgoing call.<br> * This property is required. */ public void setChannel(String channel) { this.channel = channel; } /** * Returns the name of the context of the extension to connect to. */ public String getContext() { return context; } /** * Sets the name of the context of the extension to connect to.<br> * If you set the context you also have to set the exten and priority * properties. */ public void setContext(String context) { this.context = context; } /** * Returns the extension to connect to. */ public String getExten() { return exten; } /** * Sets the extension to connect to.<br> * If you set the extension you also have to set the context and priority * properties. */ public void setExten(String exten) { this.exten = exten; } /** * Returns the priority of the extension to connect to. */ public Integer getPriority() { return priority; } /** * Sets the priority of the extension to connect to. If you set the priority * you also have to set the context and exten properties. */ public void setPriority(Integer priority) { this.priority = priority; } /** * Returns the name of the application to connect to. */ public String getApplication() { return application; } /** * Sets the name of the application to connect to. */ public void setApplication(String application) { this.application = application; } /** * Returns the parameters to pass to the application. */ public String getData() { return data; } /** * Sets the parameters to pass to the application. */ public void setData(String data) { this.data = data; } /** * Returns the timeout for the origination. */ public Integer getTimeout() { return timeout; } /** * Sets the timeout (in milliseconds) for the origination.<br> * The channel must be answered within this time, otherwise the origination * is considered to have failed and an OriginateFailureEvent is generated.<br> * If not set, asterisk assumes a default value of 30000 meaning 30 seconds. */ public void setTimeout(Integer timeout) { this.timeout = timeout; } /** * Returns the variables to set on the originated call. */ public Map getVariables() { return variables; } /** * Sets the variables to set on the originated call. */ public void setVariables(Map variables) { this.variables = variables; } /** * Sets a variable on the originated call. Replaces any existing variable * with the same name. */ public void setVariable(String name, String value) { variables.put(name, value); } /** * Returns the variables to set on the originated call in native asterisk * format.<br> * Example: "VAR1=abc|VAR2=def". */ public String getVariableString() { StringBuffer varstring = new StringBuffer(); Iterator i = variables.entrySet().iterator(); while (i.hasNext()) { Map.Entry var = (Map.Entry) i.next(); varstring.append(var.getKey()); varstring.append("|"); varstring.append(var.getValue()); } return varstring.toString(); } } Index: DefaultAsteriskManager.java =================================================================== RCS file: /cvsroot/asterisk-java/asterisk-java/src/java/net/sf/asterisk/manager/DefaultAsteriskManager.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -p -r1.4 -r1.5 --- DefaultAsteriskManager.java 31 Mar 2005 22:29:50 -0000 1.4 +++ DefaultAsteriskManager.java 22 Jun 2005 18:27:12 -0000 1.5 @@ -36,6 +36,8 @@ import net.sf.asterisk.manager.event.Man import net.sf.asterisk.manager.event.NewChannelEvent; import net.sf.asterisk.manager.event.NewExtenEvent; import net.sf.asterisk.manager.event.NewStateEvent; +import net.sf.asterisk.manager.event.OriginateFailureEvent; +import net.sf.asterisk.manager.event.OriginateSuccessEvent; import net.sf.asterisk.manager.event.QueueEntryEvent; import net.sf.asterisk.manager.event.QueueMemberEvent; import net.sf.asterisk.manager.event.QueueParamsEvent; @@ -52,7 +54,10 @@ import net.sf.asterisk.util.LogFactory; * @author srt * @version $Id$ */ -public class DefaultAsteriskManager implements AsteriskManager, ManagerEventHandler +public class DefaultAsteriskManager + implements + AsteriskManager, + ManagerEventHandler { private final Log log = LogFactory.getLog(this.getClass()); private ManagerConnection connection; @@ -61,6 +66,17 @@ public class DefaultAsteriskManager impl * A map of all active channel by their unique id. */ private Map channels; + + /** + * A map of all of the originating calls by their actionid. + */ + private Map calls; + + /** + * Sequence to track calls. + */ + private int callSequence; + private Map queues; private List queuedEvents; private boolean channelsInitialized; @@ -70,6 +86,7 @@ public class DefaultAsteriskManager impl public DefaultAsteriskManager() { + this.calls = Collections.synchronizedMap(new HashMap()); this.channels = Collections.synchronizedMap(new HashMap()); this.queues = Collections.synchronizedMap(new HashMap()); this.queuedEvents = Collections.synchronizedList(new ArrayList()); @@ -85,23 +102,65 @@ public class DefaultAsteriskManager impl this.connection = connection; } - public void initialize() throws TimeoutException, IOException, AuthenticationFailedException + public void initialize() throws TimeoutException, IOException, + AuthenticationFailedException { connection.addEventHandler(this); connection.login(); - + loggedIn = true; connection.sendAction(new StatusAction()); connection.sendAction(new QueueStatusAction()); } - public String originateCall(OriginateAction originateAction) throws TimeoutException, IOException + public Call originateCall(Originate originate) throws TimeoutException, + IOException, Exception { - ManagerResponse response; + Call call; + OriginateAction originateAction; + String actionid; - response = connection.sendAction(originateAction); + call = new Call(); + originateAction = new OriginateAction(); + actionid = System.identityHashCode(this) + "#" + (++callSequence); - return response == null ? null : response.getUniqueId(); + // set the action properties + originateAction.setAccount(originate.getAccount()); + originateAction.setApplication(originate.getApplication()); + originateAction.setCallerId(originate.getCallerId()); + originateAction.setChannel(originate.getChannel()); + originateAction.setContext(originate.getContext()); + originateAction.setData(originate.getData()); + originateAction.setExten(originate.getExten()); + originateAction.setPriority(originate.getPriority()); + originateAction.setTimeout(originate.getTimeout()); + originateAction.setVariable(originate.getVariableString()); + + // must set async to true to receive OriginateEvents. + originateAction.setAsync(Boolean.TRUE); + originateAction.setActionId(actionid); + + ManagerResponse response = connection.sendAction(originateAction); + // TODO check the response, don't bother waiting for an originatesuccess + // or originatefailure if the response is bad + + if ("Success".equalsIgnoreCase(response.getResponse())) + { + // register and listen for the OriginateSuccess or OriginateFailure + // event + synchronized (call) + { + calls.put(actionid, call); + call.wait(); + } + } + else + { + call.setStartTime(new Date()); + call.setEndTime(call.getStartTime()); + } + + return call; } /** @@ -119,8 +178,8 @@ public class DefaultAsteriskManager impl /** * Handles all events received from the asterisk server.<br> - * Events are queued until channels and queues are initialized and then delegated to the - * dispatchEvent method. + * Events are queued until channels and queues are initialized and then + * delegated to the dispatchEvent method. */ public void handleEvent(ManagerEvent event) { @@ -213,6 +272,14 @@ public class DefaultAsteriskManager impl { handleHangupEvent((HangupEvent) event); } + else if (event instanceof OriginateSuccessEvent) + { + handleOriginateSuccessEvent((OriginateSuccessEvent) event); + } + else if (event instanceof OriginateFailureEvent) + { + handleOriginateFailureEvent((OriginateFailureEvent) event); + } } protected void addChannel(Channel channel) @@ -246,8 +313,8 @@ public class DefaultAsteriskManager impl channel = new Channel(event.getChannel(), event.getUniqueId()); if (event.getSeconds() != null) { - channel - .setDateOfCreation(new Date(System.currentTimeMillis() - (event.getSeconds().intValue() * 1000))); + channel.setDateOfCreation(new Date(System.currentTimeMillis() + - (event.getSeconds().intValue() * 1000))); } isNew = true; } @@ -288,7 +355,8 @@ public class DefaultAsteriskManager impl } /** - * Resets the internal state when the connection to the asterisk server is lost. + * Resets the internal state when the connection to the asterisk server is + * lost. */ protected void handleDisconnectEvent(DisconnectEvent disconnectEvent) { @@ -302,8 +370,8 @@ public class DefaultAsteriskManager impl } /** - * Requests the current state from the asterisk server after the connection to the asterisk - * server is restored. + * Requests the current state from the asterisk server after the connection + * to the asterisk server is restored. */ protected void handleConnectEvent(ConnectEvent connectEvent) { @@ -319,7 +387,7 @@ public class DefaultAsteriskManager impl } catch (Exception e) { - log.error("Unable to request channel status from asterisk server after reconnect.", e); + log.error("Unable to request channel status after reconnect.", e); } try @@ -328,7 +396,7 @@ public class DefaultAsteriskManager impl } catch (Exception e) { - log.error("Unable to request queue status from asterisk server after reconnect.", e); + log.error("Unable to request queue status after reconnect.", e); } } @@ -369,12 +437,14 @@ public class DefaultAsteriskManager impl if (queue == null) { - log.error("ignored QueueEntryEvent for unknown queue " + event.getQueue()); + log.error("ignored QueueEntryEvent for unknown queue " + + event.getQueue()); return; } if (channel == null) { - log.error("ignored QueueEntryEvent for unknown channel " + event.getChannel()); + log.error("ignored QueueEntryEvent for unknown channel " + + event.getChannel()); return; } @@ -422,7 +492,8 @@ public class DefaultAsteriskManager impl Channel channel = (Channel) channels.get(event.getUniqueId()); if (channel == null) { - log.error("Ignored NewExtenEvent for unknown channel " + event.getChannel()); + log.error("Ignored NewExtenEvent for unknown channel " + + event.getChannel()); return; } @@ -441,7 +512,8 @@ public class DefaultAsteriskManager impl Channel channel = (Channel) channels.get(event.getUniqueId()); if (channel == null) { - log.error("Ignored NewStateEvent for unknown channel " + event.getChannel()); + log.error("Ignored NewStateEvent for unknown channel " + + event.getChannel()); return; } @@ -453,7 +525,8 @@ public class DefaultAsteriskManager impl Channel channel = (Channel) channels.get(event.getUniqueId()); if (channel == null) { - log.error("Ignored HangupEvent for unknown channel " + event.getChannel()); + log.error("Ignored HangupEvent for unknown channel " + + event.getChannel()); return; } @@ -473,16 +546,19 @@ public class DefaultAsteriskManager impl if (channel1 == null) { - log.error("Ignored LinkEvent for unknown channel " + event.getChannel1()); + log.error("Ignored LinkEvent for unknown channel " + + event.getChannel1()); return; } if (channel2 == null) { - log.error("Ignored LinkEvent for unknown channel " + event.getChannel2()); + log.error("Ignored LinkEvent for unknown channel " + + event.getChannel2()); return; } - log.info("Linking channels " + channel1.getName() + " and " + channel2.getName()); + log.info("Linking channels " + channel1.getName() + " and " + + channel2.getName()); synchronized (this) { channel1.setLinkedChannel(channel2); @@ -497,16 +573,19 @@ public class DefaultAsteriskManager impl if (channel1 == null) { - log.error("Ignored UnlinkEvent for unknown channel " + event.getChannel1()); + log.error("Ignored UnlinkEvent for unknown channel " + + event.getChannel1()); return; } if (channel2 == null) { - log.error("Ignored UnlinkEvent for unknown channel " + event.getChannel2()); + log.error("Ignored UnlinkEvent for unknown channel " + + event.getChannel2()); return; } - log.info("Unlinking channels " + channel1.getName() + " and " + channel2.getName()); + log.info("Unlinking channels " + channel1.getName() + " and " + + channel2.getName()); synchronized (channel1) { channel1.setLinkedChannel(null); @@ -522,7 +601,64 @@ public class DefaultAsteriskManager impl { Channel channel = (Channel) channels.get(event.getUniqueId()); - log.info("Renaming channel '" + channel.getName() + "' to '" + event.getNewname() + "'"); + log.info("Renaming channel '" + channel.getName() + "' to '" + + event.getNewname() + "'"); channel.setName(event.getNewname()); } + + protected void handleOriginateSuccessEvent(OriginateSuccessEvent event) + { + log.debug("Got OriginateSuccess Event" + event); + // see if there is a call registered for this actionid + synchronized (calls) + { + Call call = (Call) calls.get(event.getActionId()); + log.debug("Found a call waiting for this OriginateSuccess event"); + // update the call and notify that it is ready + if (call != null) + { + synchronized (call) + { + Channel channel; + + calls.remove(call); + + channel = (Channel) channels.get(event.getUniqueId()); + call.setUniqueId(event.getUniqueId()); + call.setChannel(channel); + call.setStartTime(event.getDateReceived()); + call.setReason(event.getReason()); + call.notify(); + } + } + } + } + + protected void handleOriginateFailureEvent(OriginateFailureEvent event) + { + // see if there is a call registered for this actionid + synchronized (calls) + { + Call call = (Call) calls.get(event.getActionId()); + + // update the call and notify that it is ready + if (call != null) + { + synchronized (call) + { + Channel channel; + + calls.remove(call); + + channel = (Channel) channels.get(event.getUniqueId()); + call.setUniqueId(event.getUniqueId()); + call.setChannel(channel); + call.setStartTime(event.getDateReceived()); + call.setEndTime(event.getDateReceived()); + call.setReason(event.getReason()); + call.notify(); + } + } + } + } } Index: AsteriskManager.java =================================================================== RCS file: /cvsroot/asterisk-java/asterisk-java/src/java/net/sf/asterisk/manager/AsteriskManager.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -p -r1.4 -r1.5 --- AsteriskManager.java 23 Feb 2005 22:50:57 -0000 1.4 +++ AsteriskManager.java 22 Jun 2005 18:27:12 -0000 1.5 @@ -19,8 +19,6 @@ package net.sf.asterisk.manager; import java.io.IOException; import java.util.Map; -import net.sf.asterisk.manager.action.OriginateAction; - /** * @author srt * @version $Id$ @@ -30,13 +28,13 @@ public interface AsteriskManager /** * Generates an outgoing call. * - * @param originateAction conatins the details of the call to originate - * @return the unique id of the created channel (this one is also found in the cdr) + * @param originate conatins the details of the call to originate + * @return a Call object representing the originated call * * @throws TimeoutException if the originated call is not answered in time * @throws IOException if the action cannot be sent to the asterisk server */ - String originateCall(OriginateAction originateAction) throws TimeoutException, IOException; + public Call originateCall(Originate originate) throws TimeoutException, IOException, Exception; /** * Returns a Map of active channels.<br> Index: MultiAsterisksManager.java =================================================================== RCS file: /cvsroot/asterisk-java/asterisk-java/src/java/net/sf/asterisk/manager/MultiAsterisksManager.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -p -r1.3 -r1.4 --- MultiAsterisksManager.java 31 Mar 2005 22:29:50 -0000 1.3 +++ MultiAsterisksManager.java 22 Jun 2005 18:27:12 -0000 1.4 @@ -456,7 +456,7 @@ public class MultiAsterisksManager imple * * @see net.sf.asterisk.manager.AsteriskManager#originateCall(net.sf.asterisk.manager.action.OriginateAction) */ - public String originateCall(OriginateAction originateAction) throws TimeoutException, IOException + public Call originateCall(Originate originate) throws TimeoutException, IOException { // TODO Auto-generated method stub return null; |