org.asteriskjava.manager.action.OriginateAction Maven / Gradle / Ivy
Show all versions of asterisk-java Show documentation
/*
* 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 implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.asteriskjava.manager.action;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.asteriskjava.manager.event.OriginateResponseEvent;
import org.asteriskjava.manager.event.ResponseEvent;
import org.asteriskjava.util.Log;
import org.asteriskjava.util.LogFactory;
/**
* The OriginateAction generates an outgoing call to the extension in the given
* context with the given priority or to a given application with optional
* parameters.
*
* If you want to connect to an extension use the properties context, exten and
* priority. If you want to connect to an application use the properties
* application and data if needed. Note that no call detail record will be
* written when directly connecting to an application, so it may be better to
* connect to an extension that starts the application you wish to connect to.
*
* The response to this action is sent when the channel has been answered and
* asterisk starts connecting it to the given extension. So be careful not to
* choose a too short timeout when waiting for the response.
*
* If you set async to true
Asterisk reports an OriginateSuccess-
* and OriginateFailureEvents. The action id of these events equals the action
* id of this OriginateAction.
*
* @author srt
* @version $Id$
* @see org.asteriskjava.manager.event.OriginateResponseEvent
*/
public class OriginateAction extends AbstractManagerAction implements EventGeneratingAction
{
private final Log logger = LogFactory.getLog(getClass());
/**
* Serializable version identifier
*/
static final long serialVersionUID = 8194597741743334704L;
private String channel;
private String exten;
private String context;
private Integer priority;
private Long timeout;
private String callerId;
private Integer callingPres;
private Map variables;
private String account;
private String application;
private String data;
private Boolean async;
private String codecs;
private Boolean earlyMedia;
private String channelId;
private String otherChannelId;
// starting at ten saves on a formatter.
private int headerCounter = 10;
private Set preventDuplicateSipHeaders = new HashSet<>();
/**
* Returns the name of this action, i.e. "Originate".
*
* @return the name of this action.
*/
@Override
public String getAction()
{
return "Originate";
}
/**
* Returns the account code to use for the originated call.
*
* @return the account code to use for the originated call.
*/
public String getAccount()
{
return account;
}
/**
* Sets the account code to use for the originated call.
*
* The account code is included in the call detail record generated for this
* call and will be used for billing.
*
* @param account the account code to use for the originated call.
*/
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.
*
* This includes both the Caller*Id Number and Caller*Id Name in the form
* "Jon Doe <1234>".
*
* @param callerId the caller id to set on the outgoing channel.
*/
public void setCallerId(String callerId)
{
this.callerId = callerId;
}
/**
* Returns the calling presentation for the outgoing channel.
*
* This property is only available on BRIstuffed Asterisk servers.
*
* @return the calling presentation for the outgoing channel.
* @see #setCallingPres(Integer)
*/
public Integer getCallingPres()
{
return callingPres;
}
/**
* Sets the calling presentation for the outgoing channel.
*
* The number is an octet and the only bits you need worry about are bits
* 1,2,6 and 7.
*
* Bits 1 and 2 define the screening indicator and bits 6 and 7 define the
* presentation indicator.
*
* In essence, it says, 'Is the person who has been called allowed to see
* the callers number?' (presentation) and 'What authority was used to
* verify that this is a genuine number?' (screening).
*
*
* Presentation indicator (Bits 6 and 7):
*
*
* Bits Meaning
* 7 6
* 0 0 Presentation allowed
* 0 1 Presentation restricted
* 1 0 Number not available due to interworking
* 1 1 Reserved
*
*
* Screening indicator (Bits 1 and 2):
*
*
* Bits Meaning
* 2 1
* 0 0 User-provided, not screened
* 0 1 User-provided, verified and passed
* 1 0 User-provided, verified and failed
* 1 1 Network provided
*
*
* Examples for some general settings:
*
*
* Presentation Allowed, Network Provided: 3 (00000011)
* Presentation Restricted, User-provided, not screened: 32 (00100000)
* Presentation Restricted, User-provided, verified, and passed: 33 (00100001)
* Presentation Restricted, Network Provided: 35 (00100011)
*
*
* This property is only available on BRIstuffed Asterisk servers.
*
* @param callingPres the calling presentation for the outgoing channel.
*/
public void setCallingPres(Integer callingPres)
{
this.callingPres = callingPres;
}
/**
* 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.
*
* This property is mandatory.
*/
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.
*
* 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.
*
* 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 Long getTimeout()
{
return timeout;
}
/**
* Sets the timeout (in milliseconds) for the origination.
*
* The channel must be answered within this time, otherwise the origination
* is considered to have failed and an OriginateFailureEvent is generated.
*
* If not set, Asterisk assumes a default value of 30000 meaning 30 seconds.
*
* @param timeout the timeout in milliseconds
* @deprecated use {@link #setTimeout(Long)} instead.
*/
@Deprecated
public void setTimeout(Integer timeout)
{
if (timeout != null)
{
if (timeout < 1000)
{
logger.error("A timeout of 1000 will cause the originate to almost cretainly fail!");
}
if (timeout < 10000)
{
logger.warn(
"A timeout of less than 10000 will cause the originate to fail if not answered within 10 seconds!");
}
this.timeout = timeout.longValue();
}
else
{
this.timeout = null;
}
}
/**
* Sets the timeout (in milliseconds) for the origination.
*
* The channel must be answered within this time, otherwise the origination
* is considered to have failed and an OriginateFailureEvent is generated.
*
* If not set, Asterisk assumes a default value of 30000 meaning 30 seconds.
*
* @param timeout the timeout in milliseconds
*/
public void setTimeout(Long timeout)
{
if (timeout != null)
{
if (timeout < 1000)
{
logger.error("A timeout of 1000 will cause the originate to almost cretainly fail!");
}
if (timeout < 10000)
{
logger.warn(
"A timeout of less than 100000 will cause the originate to fail if not answered within 10 seconds!");
}
}
this.timeout = timeout;
}
/**
* Sets the variables to set on the originated call.
*
* Variable assignments are of the form "VARNAME=VALUE". You can specify
* multiple variable assignments separated by the '|' character.
*
* Example: "VAR1=abc|VAR2=def" sets the channel variables VAR1 to "abc" and
* VAR2 to "def".
*
* @deprecated use {@link #setVariables(Map)} instead.
*/
@Deprecated
public void setVariable(String variable)
{
final StringTokenizer st;
if (variable == null)
{
this.variables = null;
return;
}
st = new StringTokenizer(variable, "|");
variables = new LinkedHashMap<>();
while (st.hasMoreTokens())
{
String[] keyValue;
keyValue = st.nextToken().split("=", 2);
if (keyValue.length < 2)
{
variables.put(keyValue[0], null);
}
else
{
variables.put(keyValue[0], keyValue[1]);
}
}
}
/**
* Sets an variable on the originated call.
*
* @param name the name of the variable to set.
* @param value the value of the variable to set.
* @since 0.3
*/
public void setVariable(String name, String value)
{
if (variables == null)
{
variables = new LinkedHashMap<>();
}
variables.put(name, value);
}
/**
* Returns the variables to set on the originated call.
*
* @return a Map containing the variable names as key and their values as
* value.
* @since 0.2
*/
public Map getVariables()
{
return variables;
}
/**
* Sets the variables to set on the originated call.
*
* @param variables a Map containing the variable names as key and their
* values as value.
* @since 0.2
*/
public void setVariables(Map variables)
{
if (this.variables != null)
{
this.variables.putAll(variables);
}
else
{
this.variables = variables;
}
}
/**
* Returns true if this is a fast origination.
*/
public Boolean getAsync()
{
return async;
}
/**
* Set to true for fast origination. Only with fast origination Asterisk
* will send OriginateSuccess- and OriginateFailureEvents.
*/
public void setAsync(Boolean async)
{
this.async = async;
}
/**
* @param earlyMedia the earlyMedia to set
*/
public void setEarlyMedia(Boolean earlyMedia)
{
this.earlyMedia = earlyMedia;
}
/**
* @return the earlyMedia
*/
public Boolean getEarlyMedia()
{
return earlyMedia;
}
/**
* Returns the codecs to use for the call.
*
* @return the codecs to use for the call.
* @since 1.0.0
*/
public String getCodecs()
{
return codecs;
}
/**
* Sets the codecs to use for the call. For example "alaw, ulaw, h264".
*
* Available since Asterisk 1.6.
*
* @param codecs comma separated list of codecs to use for the call.
* @since 1.0.0
*/
public void setCodecs(String codecs)
{
this.codecs = codecs;
}
/**
* Sets the codecs to use for the call.
*
* Available since Asterisk 1.6.
*
* @param codecs list of codecs to use for the call.
* @since 1.0.0
*/
public void setCodecs(List codecs)
{
if (codecs == null || codecs.isEmpty())
{
this.codecs = null;
return;
}
Iterator iter = codecs.iterator();
StringBuilder buffer = new StringBuilder(iter.next());
while (iter.hasNext())
{
buffer.append(",").append(iter.next());
}
this.codecs = buffer.toString();
}
public Class< ? extends ResponseEvent> getActionCompleteEventClass()
{
return OriginateResponseEvent.class;
}
public void addSipHeader(VariableInheritance inheritance, String header)
{
if (!preventDuplicateSipHeaders.contains(header))
{
setVariable(inheritance.getPrefix() + "SIPADDHEADER" + (headerCounter++), header);
preventDuplicateSipHeaders.add(header);
if (headerCounter > 50)
{
logger.warn("I think only 50 headers are allowed by asterisk?");
}
}
else
{
logger.error("Already added the sip header " + header);
}
}
public void addPjSipHeader(VariableInheritance inheritance, String header)
{
if (header != null)
{
String[] parts = header.split(":");
if (parts.length == 2)
{
String varName = "PJSIP_HEADER" + "(add," + parts[0] + ")";
String varValue = parts[1];
if (!preventDuplicateSipHeaders.contains(header))
{
setVariable(varName, varValue);
preventDuplicateSipHeaders.add(header);
}
else
{
logger.error("Already added the sip header " + header);
}
}
}
}
/**
* this will be the channels uniqueID
*
* @param channelId
*/
public void setChannelId(String channelId)
{
this.channelId = channelId;
}
public String getChannelId()
{
return channelId;
}
public void setOtherChannelId(String otherChannelId)
{
this.otherChannelId = otherChannelId;
}
public String getOtherChannelId()
{
return otherChannelId;
}
}