package net.sourceforge.gjtapi.raw.asterisk;
import net.sourceforge.gjtapi.raw.*;
import net.sourceforge.gjtapi.*;
import net.sourceforge.gjtapi.capabilities.Capabilities;
import net.sf.asterisk.manager.*;
import net.sf.asterisk.manager.event.*;
import net.sf.asterisk.manager.response.*;
import net.sf.asterisk.manager.response.CommandResponse;
import net.sf.asterisk.manager.action.*;
import javax.telephony.*;
import java.util.*;
import java.io.*;
/**
*
* an AsteriskProvider
* @author Johannes Boesl - ADITO Software GmbH, 20.06.2005
*/
public class AsteriskProvider implements BasicJtapiTpi, CCTpi
{
private DefaultAsteriskManager asteriskManager;
private DefaultManagerConnection managerConnection;
private Set listeners;
private Set callSet;
private String[] addresses;
private TermData[] terminals;
private boolean gJtapiSetsStateOnItsOwnOnCallCreate;
private List addressePrefixes;
private String conferenceContext;
private int conferenceCounter = 0;
private String context;
private Map confrenceMap;
private int TIMEOUT = 10000;
private boolean OUT = false;
public AsteriskProvider()
{
super();
listeners = new HashSet();
callSet = new HashSet();
confrenceMap = new HashMap();
}
public void addListener(TelephonyListener ro)
{
listeners.add(ro);
}
public void removeListener(TelephonyListener ro)
{
listeners.remove(ro);
}
/**
* seems as this is not supported by asterisk
*/
public void answerCall(CallId call, String address, String terminal) throws PrivilegeViolationException, ResourceUnavailableException,
MethodNotSupportedException, RawStateException
{
throw new MethodNotSupportedException("answering callSet is not supported by asterisk");
}
public CallId createCall(CallId id, String address, String term, String dest) throws ResourceUnavailableException, PrivilegeViolationException,
InvalidPartyException, InvalidArgumentException, RawStateException,
MethodNotSupportedException
{
final OriginateAction originateAction;
originateAction = new OriginateAction();
originateAction.setChannel(address);
originateAction.setContext(context);
originateAction.setCallerId(getAsteriskCallerIdForAddress(address));
originateAction.setAsync(Boolean.TRUE);
originateAction.setExten(dest);
originateAction.setPriority(new Integer(1));
originateAction.setTimeout(new Long(TIMEOUT));
try
{
ManagerResponse response = managerConnection.sendAction(originateAction);
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
_o(response.toString());
String uniqueId = response.getUniqueId();
Channel chan = getChannelForUniqueId(uniqueId);
if(gJtapiSetsStateOnItsOwnOnCallCreate)
{
AsteriskConnectionDetail detail = new AsteriskConnectionDetail
(uniqueId, chan, address, dest);
((AsteriskCallId)id).addConnection(response.getUniqueId(), detail);
_o("set the ID: " + response.getUniqueId() + "\t\t" + response.getResponse());
}
}
catch (IOException e)
{
e.printStackTrace();
}
catch (TimeoutException e)
{
e.printStackTrace();
}
return null;
}
public void hold(CallId call, String address, String terminal) throws RawStateException, MethodNotSupportedException,
PrivilegeViolationException, ResourceUnavailableException
{
throw new MethodNotSupportedException("holding callSet is not supported by asterisk provider");
}
public CallId join(CallId call1, CallId call2, String address, String terminal) throws RawStateException, InvalidArgumentException,
MethodNotSupportedException, PrivilegeViolationException, ResourceUnavailableException
{
if(!(call1 instanceof AsteriskCallId) || !(call2 instanceof AsteriskCallId))
throw new InvalidArgumentException("at least one callId isn't an AsteriskCallId");
_o("\t\tjoin called for: " + call1 + " and " + call2);
AsteriskCallId aCId1 = (AsteriskCallId)call1;
AsteriskCallId aCId2 = (AsteriskCallId)call2;
AsteriskConnectionDetail aCDi1 = getCallingDetail(aCId1);
AsteriskConnectionDetail aCDi2 = getCallingDetail(aCId2);
String myCallerId = "";
if(aCDi1.address.equals(aCDi2.address) &&
isOneOfMyAddresses(getAddressForAsteriskCallerId(aCDi1.address)))
myCallerId = aCDi1.address;
else if(aCDi1.address.equals(aCDi2.calledAddress) &&
isOneOfMyAddresses(getAddressForAsteriskCallerId(aCDi1.address)))
myCallerId = aCDi1.address;
else if(aCDi1.calledAddress.equals(aCDi2.address) &&
isOneOfMyAddresses(getAddressForAsteriskCallerId(aCDi1.calledAddress)))
myCallerId = aCDi1.calledAddress;
else if(aCDi1.calledAddress.equals(aCDi2.calledAddress) &&
isOneOfMyAddresses(getAddressForAsteriskCallerId(aCDi1.calledAddress)))
myCallerId = aCDi1.calledAddress;
_o("\t\tmyCallerId: " + myCallerId);
AsteriskConnectionDetail myDetail1 = getDetailForCallerId(aCId1, myCallerId);
AsteriskConnectionDetail myDetail2 = getDetailForCallerId(aCId2, myCallerId);
AsteriskConnectionDetail[] otherDetails1 = getDetailsForNotCallerId(aCId1, myCallerId);
AsteriskConnectionDetail[] otherDetails2 = getDetailsForNotCallerId(aCId2, myCallerId);
String myExt = "";
boolean newConf = false;
if(aCId1.getConferenceRoom() != null)
myExt = aCId1.getConferenceRoom();
else if(aCId2.getConferenceRoom() != null)
myExt = aCId2.getConferenceRoom();
else
{
myExt = myCallerId + conferenceCounter++%100;
newConf = true;
}
_o(getChannelForUniqueId(myDetail1.uniqueId).toString());
try
{
for(int i = newConf?1:0; i < otherDetails1.length; i++) // i = newConf?1:0 !
{
RedirectAction redAct = new RedirectAction(otherDetails1[i].channel.getName(),
conferenceContext, myExt, new Integer(1));
ManagerResponse resp = managerConnection.sendAction(redAct);
_o("\t\tsecond response " + i + " " + resp.getResponse() + " " + resp.getMessage());
}
{
RedirectAction redAct = null;
if(newConf)
redAct = new RedirectAction(myDetail1.channel.getName(),
otherDetails1[0].channel.getName(), conferenceContext, myExt, new Integer(1));
else
redAct = new RedirectAction(myDetail1.channel.getName(), conferenceContext, myExt, new Integer(1));
ManagerResponse resp = managerConnection.sendAction(redAct);
_o("\t\tfirst response " + resp.getResponse() + " " + resp.getMessage());
}
for(int i = 0; i < otherDetails2.length; i++)
{
RedirectAction redAct = new RedirectAction(otherDetails2[i].channel.getName(),
conferenceContext, myExt, new Integer(1));
ManagerResponse resp = managerConnection.sendAction(redAct);
_o("\t\tthird response " + i + " " + resp.getResponse() + " " + resp.getMessage());
}
hangUpChannel(myDetail2.channel.getName());
}
catch (IOException e)
{
e.printStackTrace();
}
catch (TimeoutException e)
{
e.printStackTrace();
}
return aCId1;
}
public void unHold(CallId call, String address, String terminal) throws RawStateException, MethodNotSupportedException,
PrivilegeViolationException, ResourceUnavailableException
{
throw new MethodNotSupportedException("unholding callSet is not supported by asterisk provider");
}
public void release(String address, CallId call) throws PrivilegeViolationException,
ResourceUnavailableException, MethodNotSupportedException, RawStateException
{
_o("address: " + address + "\t\tcallid: " + call.toString());
if(callSet.contains(call))
{
AsteriskCallId aCId = (AsteriskCallId)call;
String channel2Hangup = null;
_o("connections: " + aCId.getConnections().size() + "\t\tmyId: " + aCId.getCallId());
for(Iterator i = aCId.getConnections().keySet().iterator(); i.hasNext(); )
{
AsteriskConnectionDetail detail = getDetail(aCId, i.next().toString());
if(detail != null && detail.channel != null)
{
_o("release debug: " + detail.channel.toString());
if(aCId.getCallId().equals(detail.address))
{
channel2Hangup = detail.channel.getName();
aCId.removeConnection(detail.uniqueId);
break;
}
}
}
if(channel2Hangup != null)
hangUpChannel(channel2Hangup);
}
}
public Properties getCapabilities()
{
Properties capabilities = new Properties();
capabilities.put(Capabilities.THROTTLE, "f");
capabilities.put(Capabilities.MEDIA, "f");
capabilities.put(Capabilities.ALL_MEDIA_TERMINALS, "f");
capabilities.put(Capabilities.ALLOCATE_MEDIA, "f");
return capabilities;
}
public void releaseCallId(CallId id)
{
callSet.remove(id);
}
public CallId reserveCallId(String address) throws InvalidArgumentException
{
CallId call = new AsteriskCallId(address);
callSet.add(call);
return call;
}
public void shutdown()
{
try
{
managerConnection.logoff();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (TimeoutException e)
{
e.printStackTrace();
}
}
/**
* lists only sip-addresses
* @return
* @throws ResourceUnavailableException
*/
public String[] getAddresses() throws ResourceUnavailableException
{
if(addresses == null)
{
CommandAction command = new CommandAction();
command.setCommand("sip show users");
CommandResponse cr = null;
try
{
cr = (CommandResponse)managerConnection.sendAction(command);
}
catch (IOException e)
{
e.printStackTrace();
}
catch (TimeoutException e)
{
e.printStackTrace();
}
Object[] result = cr.getResult().toArray();
addresses = new String[result.length-1];
for(int i = 1; i < result.length; i++)
addresses[i-1] = "SIP/" + result[i].toString().split(" ")[0];
}
return addresses;
}
public String[] getAddresses(String terminal) throws InvalidArgumentException
{
try
{
for(int i = 0; i < getAddresses().length; i++)
{
if(getAddresses()[i].equals(terminal))
return new String[]{terminal};
}
}
catch (ResourceUnavailableException e)
{
}
throw new InvalidArgumentException("no terminal " + terminal);
}
public TermData[] getTerminals() throws ResourceUnavailableException
{
if(terminals == null)
{
terminals = new TermData[getAddresses().length];
for(int i = 0; i < getAddresses().length; i++)
{
terminals[i] = new TermData(getAddresses()[i], false);
}
}
return terminals;
}
public TermData[] getTerminals(String address) throws InvalidArgumentException
{
return new TermData[]{new TermData(getAddresses(address)[0], false)};
}
public void initialize(Map props) throws ProviderUnavailableException
{
managerConnection = new DefaultManagerConnection();
asteriskManager = new DefaultAsteriskManager();
Object server = props.get("Server");
Object port = props.get("Port");
Object user = props.get("User");
Object password = props.get("Password");
Object context = props.get("Context");
Object phone = props.get("Phone");
Object gJtapiSetsState = props.get("GJtapiSetsState");
Object confCont = props.get("ConferenceContext");
managerConnection.setHostname(server==null? null: server.toString());
managerConnection.setPort(Integer.parseInt(port==null? "5038": port.toString()));
managerConnection.setUsername(user==null? null: user.toString());
managerConnection.setPassword(password==null? null: password.toString());
this.context = context==null? null: context.toString();
this.addresses = phone==null? null: new String[]{phone.toString()};
gJtapiSetsStateOnItsOwnOnCallCreate = gJtapiSetsState==null? true: Boolean.valueOf(gJtapiSetsState.toString()).booleanValue();
conferenceContext = confCont==null? null: confCont.toString();
asteriskManager.setManagerConnection(managerConnection);
try
{
asteriskManager.initialize();
}
catch (IOException e)
{
throw new ProviderUnavailableException(e.toString());
}
catch (AuthenticationFailedException e)
{
throw new ProviderUnavailableException(e.toString());
}
catch (TimeoutException e)
{
throw new ProviderUnavailableException(e.toString());
}
managerConnection.addEventHandler(getManagerEventHandler());
}
/**
* these are the events got by AsteriskJava
*/
private ManagerEventHandler getManagerEventHandler()
{
return new ManagerEventHandler()
{
public void handleEvent(ManagerEvent event)
{
try
{
if (event.getClass().equals(AgentCallbackLoginEvent.class))
{
_o("AgentCallbackLoginEvent");
}
else if (event.getClass().equals(AgentCallbackLogoffEvent.class))
{
_o("AgentCallbackLogoffEvent");
}
else if (event.getClass().equals(AgentCalledEvent.class))
{
_o("AgentCalledEvent");
}
else if (event.getClass().equals(AgentLoginEvent.class))
{
_o("AgentLoginEvent");
}
else if (event.getClass().equals(AgentLogoffEvent.class))
{
_o("AgentLogoffEvent");
}
else if (event.getClass().equals(AlarmClearEvent.class))
{
_o("AlarmClearEvent");
}
else if (event.getClass().equals(AlarmEvent.class))
{
_o("AlarmEvent");
}
else if (event.getClass().equals(CdrEvent.class))
{
_o("CdrEvent");
}
else if (event.getClass().equals(ChannelEvent.class))
{
_o("ChannelEvent");
}
else if (event.getClass().equals(ConnectEvent.class))
{
_o("ConnectEvent");
}
else if (event.getClass().equals(DialEvent.class))
{
_o("DialEvent");
DialEvent ev = (DialEvent)event;
AsteriskCallId[] calls = getCallIdsForUniqueId(ev.getSrcUniqueId());
if(calls.length != 0)
{
for(int i = 0; i < calls.length; i++)
{
AsteriskConnectionDetail callerDetail = getDetail(calls[i], ev.getSrcUniqueId());
if(callerDetail.calledAddress != null)
{
getChannelForUniqueId(ev.getDestUniqueId()).setCallerId(callerDetail.calledAddress);
AsteriskConnectionDetail aDetail = new AsteriskConnectionDetail
(
ev.getDestUniqueId(),
getChannelForUniqueId(ev.getDestUniqueId()),
callerDetail.calledAddress,
null
);
calls[i].addConnection(ev.getDestUniqueId(), aDetail);
String[] det = adjustCallingCalled(calls[i].getCallId(), callerDetail.address, callerDetail.calledAddress);
String callingAddress = det[0];
String calledAddress = det[1];
_o("called " + calledAddress + "\t\tcalling " + callingAddress + "\t\tthis one: " + calls[i].getCallId());
fireTelephonyEvent(AstTeleEventTypes.callActive, calls[i], null, Event.CAUSE_NORMAL);
if(getAddressForAsteriskCallerId(calls[i].getCallId()).equals(callingAddress))
{
fireTelephonyEvent(AstTeleEventTypes.connectionAlerting, calls[i], calledAddress, Event.CAUSE_NORMAL);
fireTelephonyEvent(AstTeleEventTypes.terminalConnectionCreated, calls[i], callingAddress, Event.CAUSE_NORMAL);
fireTelephonyEvent(AstTeleEventTypes.connectionInProgress, calls[i], callingAddress, Event.CAUSE_NORMAL);
fireTelephonyEvent(AstTeleEventTypes.connectionConnected, calls[i], calledAddress, Event.CAUSE_NORMAL);
fireTelephonyEvent(AstTeleEventTypes.terminalConnectionCreated, calls[i], calledAddress, Event.CAUSE_NORMAL);
}
else if(getAddressForAsteriskCallerId(calls[i].getCallId()).equals(calledAddress))
{
fireTelephonyEvent(AstTeleEventTypes.connectionInProgress, calls[i], callingAddress, Event.CAUSE_NORMAL);
fireTelephonyEvent(AstTeleEventTypes.connectionAlerting, calls[i], calledAddress, Event.CAUSE_NORMAL);
fireTelephonyEvent(AstTeleEventTypes.terminalConnectionCreated, calls[i], calledAddress, Event.CAUSE_NORMAL);
fireTelephonyEvent(AstTeleEventTypes.connectionConnected, calls[i], callingAddress, Event.CAUSE_NORMAL);
fireTelephonyEvent(AstTeleEventTypes.terminalConnectionCreated, calls[i], callingAddress, Event.CAUSE_NORMAL);
}
}
}
_o(ev.getCallerId() + "\t\t" + ev.getCallerIdName() + "\t\t" + ev.getDestination() + "\t\t" +
ev.getDestUniqueId() + "\t\t" + ev.getSrc() + "\t\t" + ev.getSrcUniqueId());
_o(getChannelForUniqueId(ev.getDestUniqueId()).toString());
_o(getChannelForUniqueId(ev.getSrcUniqueId()).toString());
}
}
else if (event.getClass().equals(DisconnectEvent.class))
{
_o("DisconnectEvent");
}
else if (event.getClass().equals(HangupEvent.class))
{
_o("HangupEvent");
HangupEvent ev = (HangupEvent)event;
_o(ev.getChannel() + "\t\t" + getChannelForUniqueId(ev.getUniqueId()) + "\t\t" + ev.getUniqueId());
AsteriskCallId[] calls = getCallIdsForUniqueId(ev.getUniqueId());
if (calls.length != 0)
{
for(int i = 0; i < calls.length; i++)
{
String address = null;
AsteriskConnectionDetail aDetail = getDetail(calls[i], ev.getUniqueId());
if(ev.getChannel().indexOf("<ZOMBIE>") == -1)
{
if(calls[i].getCallId().equals(aDetail.address))
address = getAddressForAsteriskCallerId(aDetail.address);
calls[i].removeConnection(ev.getUniqueId());
_o("connection removed: " + ev.getChannel());
if(calls[i].getConnections().size() == 0)
{
callSet.remove(calls[i]);
_o("call " + calls[i].toString() + " removed!");
}
}
if(address != null)
{
fireTelephonyEvent(AstTeleEventTypes.terminalConnectionDropped, calls[i], address, Event.CAUSE_NORMAL);
fireTelephonyEvent(AstTeleEventTypes.connectionDisconnected, calls[i], address, Event.CAUSE_NORMAL);
}
}
}
}
else if (event.getClass().equals(HoldedCallEvent.class))
{
_o("HoldedCallEvent");
}
else if (event.getClass().equals(JoinEvent.class))
{
_o("JoinEvent");
}
else if (event.getClass().equals(LeaveEvent.class))
{
_o("LeaveEvent");
}
else if (event.getClass().equals(LinkageEvent.class))
{
_o("LinkageEvent");
}
else if (event.getClass().equals(LinkEvent.class))
{
_o("LinkEvent");
}
else if(event .getClass().equals(ManagerEvent.class))
{
_o("ManagerEvent");
}
else if (event.getClass().equals(MeetMeEvent.class))
{
_o("MeetMeEvent");
}
else if (event.getClass().equals(MeetMeJoinEvent.class))
{
_o("MeetMeJoinEvent");
MeetMeJoinEvent ev = (MeetMeJoinEvent)event;
_o(ev.getMeetMe() + "\t\t" + ev.getUserNum() + "\t\t" + getChannelForUniqueId(ev.getUniqueId()).toString());
Channel newChan = getChannelForUniqueId(ev.getUniqueId());
List confList = (List)confrenceMap.get(ev.getMeetMe());
if(confList == null)
{
confList = new ArrayList();
confrenceMap.put(ev.getMeetMe(), confList);
}
for(Iterator it = callSet.iterator(); it.hasNext(); )
{
AsteriskCallId call = (AsteriskCallId)it.next();
Set keySet = call.getConnections().keySet();
for(Iterator it2 = keySet.iterator(); it2.hasNext(); )
{
AsteriskConnectionDetail aCDi = (AsteriskConnectionDetail)call.getConnections().get(it2.next());
if(aCDi.channel.getName().indexOf(newChan.getName()) != -1)
{
it2.remove();
_o("old chan: " + aCDi.channel);
aCDi.channel = newChan;
aCDi.uniqueId = ev.getUniqueId();
call.setConferenceRoom(ev.getMeetMe());
//put every conference join to conferenceMap to be able to put this call to other calls and vice versa
if(!confList.contains(aCDi))
confList.add(aCDi);
}
}
}
// don't know whether this is the last event -> do it each time
for(Iterator it = callSet.iterator(); it.hasNext(); )
{
AsteriskCallId call = (AsteriskCallId)it.next();
if(ev.getMeetMe().equals(call.getConferenceRoom()))
{
for(Iterator it2 = confList.iterator(); it2.hasNext(); )
{
AsteriskConnectionDetail aCDi = (AsteriskConnectionDetail)it2.next();
call.getConnections().put(aCDi.uniqueId, aCDi);
}
}
}
}
else if (event.getClass().equals(MeetMeLeaveEvent.class))
{
_o("MeetMeLeaveEvent");
MeetMeLeaveEvent ev = (MeetMeLeaveEvent)event;
_o(ev.getMeetMe() + "\t\t" + ev.getUserNum() + "\t\t" + getChannelForUniqueId(ev.getUniqueId()).toString());
List confList = (List)confrenceMap.get(ev.getMeetMe());
if(confList != null)
{
for(Iterator it = confList.iterator(); it.hasNext(); )
{
AsteriskConnectionDetail aCDi = (AsteriskConnectionDetail)it.next();
if(aCDi.uniqueId.equals(ev.getUniqueId()))
it.remove();
}
}
}
else if (event.getClass().equals(MessageWaitingEvent.class))
{
_o("MessageWaitingEvent");
}
else if (event.getClass().equals(NewCallerIdEvent.class))
{
_o("NewCallerIdEvent");
}
else if (event.getClass().equals(NewChannelEvent.class))
{
_o("NewChannelEvent");
NewChannelEvent ev = (NewChannelEvent) event;
if (ev.getState().equals("Ringing"))
{
_o("!Ringing");
_o(getChannelForUniqueId(ev.getUniqueId()).toString());
AsteriskCallId[] calls = getCallIdsForUniqueId(ev.getUniqueId());
if(calls.length != 0)
{
for(int i = 0; i < calls.length; i++)
{
AsteriskConnectionDetail callerDetail = getCallingDetail(calls[i]);
String[] det = adjustCallingCalled(calls[i].getCallId(), callerDetail.address, callerDetail.calledAddress);
fireTelephonyEvent(AstTeleEventTypes.terminalConnectionRinging, calls[i], det[0], Event.CAUSE_NORMAL);
fireTelephonyEvent(AstTeleEventTypes.terminalConnectionRinging, calls[i], det[1], Event.CAUSE_NORMAL);
}
}
}
}
else if (event.getClass().equals(NewExtenEvent.class))
{
_o("NewExtenEvent");
NewExtenEvent ev = (NewExtenEvent) event;
if (ev.getApplication().equals("Dial"))
{
_o("!Dial");
_o(ev.getAppData() + "\t\t" + ev.getApplication() + "\t\t" + ev.getChannel() + "\t\t" + ev.getExtension());
Channel chan = getChannelForUniqueId(ev.getUniqueId());
_o(chan.toString());
String callingAddress = getAsteriskCallerIdForAddress(chan.getCallerId());
String calledAddress = getAsteriskCallerIdForAddress(ev.getAppData());
int pipeIndex = (calledAddress.indexOf('|'));
if(pipeIndex != -1)
calledAddress = calledAddress.substring(0, pipeIndex);
AsteriskCallId[] calls = getCallIdsForUniqueId(ev.getUniqueId());
if(calls.length == 0)
{
if(isOneOfMyAddresses(getAddressForAsteriskCallerId(calledAddress)))
{
String calling = callingAddress;
if(calledAddress.equals(callingAddress))
calling += " (myself)";
AsteriskCallId call = new AsteriskCallId(calledAddress);
AsteriskConnectionDetail detail = new AsteriskConnectionDetail
(
ev.getUniqueId(), getChannelForUniqueId(ev.getUniqueId()), calling, calledAddress
);
call.addConnection(ev.getUniqueId(), detail);
callSet.add(call);
_o("new Call: " + call.toString() + " !!!");
}
if(isOneOfMyAddresses(getAddressForAsteriskCallerId(callingAddress)))
{
String called = calledAddress;
if(calledAddress.equals(callingAddress))
called += "(myself)";
AsteriskCallId call = new AsteriskCallId(callingAddress);
AsteriskConnectionDetail detail = new AsteriskConnectionDetail
(
ev.getUniqueId(), getChannelForUniqueId(ev.getUniqueId()), callingAddress, called
);
call.addConnection(ev.getUniqueId(), detail);
callSet.add(call);
_o("new Call: " + call.toString() + " !!!");
}
}
else
{
// doesn't need to check for more AsteriskCallIDs because this case can only occur
// when the call is done by using the jtapi-framework
AsteriskConnectionDetail aDetail = getDetail(calls[0], ev.getUniqueId());
if(aDetail != null)
aDetail.calledAddress = calledAddress;
}
_o("Calling: " + callingAddress + "\t\tCalled: " + calledAddress);
}
}
else if (event.getClass().equals(NewStateEvent.class))
{
_o("NewStateEvent");
NewStateEvent ev = (NewStateEvent) event;
if (ev.getState().equals("Up"))
{
_o("!Up");
_o(ev.getCallerId() + "\t\t" + ev.getCallerIdName() + "\t\t" + ev.getChannel());
_o(getChannelForUniqueId(ev.getUniqueId()).toString());
AsteriskCallId[] calls = getCallIdsForUniqueId(ev.getUniqueId());
if(calls.length != 0)
{
for(int i = 0; i < calls.length; i++)
{
AsteriskConnectionDetail detail = getCallingDetail(calls[i]);
String[] det = adjustCallingCalled(calls[i].getCallId(), detail.address, detail.calledAddress);
fireTelephonyEvent(AstTeleEventTypes.terminalConnectionTalking, calls[i], det[1], Event.CAUSE_NORMAL);
fireTelephonyEvent(AstTeleEventTypes.terminalConnectionTalking, calls[i], det[0], Event.CAUSE_NORMAL);
}
}
}
else if (ev.getState().equals("Ringing"))
{
_o("!Ringing");
_o(getChannelForUniqueId(ev.getUniqueId()).toString());
AsteriskCallId[] calls = getCallIdsForUniqueId(ev.getUniqueId());
if(calls.length != 0)
{
for(int i = 0; i < calls.length; i++)
{
AsteriskConnectionDetail callerDetail = getCallingDetail(calls[i]);
String[] det = adjustCallingCalled(calls[i].getCallId(), callerDetail.address, callerDetail.calledAddress);
fireTelephonyEvent(AstTeleEventTypes.terminalConnectionRinging, calls[i], det[0], Event.CAUSE_NORMAL);
fireTelephonyEvent(AstTeleEventTypes.terminalConnectionRinging, calls[i], det[1], Event.CAUSE_NORMAL);
}
}
}
}
else if (event.getClass().equals(OriginateEvent.class))
{
_o("OriginateEvent");
}
else if (event.getClass().equals(OriginateFailureEvent.class))
{
_o("OriginateFailureEvent");
}
else if (event.getClass().equals(OriginateSuccessEvent.class))
{
_o("OriginateSuccessEvent");
}
else if (event.getClass().equals(ParkedCallEvent.class))
{
_o("ParkedCallEvent");
}
else if (event.getClass().equals(ParkedCallsCompleteEvent.class))
{
_o("ParkedCallsCompleteEvent");
}
else if (event.getClass().equals(PeerStatusEvent.class))
{
_o("PeerStatusEvent");
}
else if (event.getClass().equals(QueueEntryEvent.class))
{
_o("QueueEntryEvent");
}
else if (event.getClass().equals(QueueEvent.class))
{
_o("QueueEvent");
}
else if (event.getClass().equals(QueueMemberEvent.class))
{
_o("QueueMemberEvent");
}
else if (event.getClass().equals(QueueMemberStatusEvent.class))
{
_o("QueueMemberStatusEvent");
}
else if (event.getClass().equals(QueueParamsEvent.class))
{
_o("QueueParamsEvent");
}
else if (event.getClass().equals(RegistryEvent.class))
{
_o("RegistryEvent");
}
else if (event.getClass().equals(ReloadEvent.class))
{
_o("ReloadEvent");
}
else if (event.getClass().equals(RenameEvent.class))
{
_o("RenameEvent");
}
else if (event.getClass().equals(ResponseEvent.class))
{
_o("ResponseEvent");
}
else if (event.getClass().equals(ShutdownEvent.class))
{
_o("ShutdownEvent");
}
else if (event.getClass().equals(StatusCompleteEvent.class))
{
_o("StatusCompleteEvent");
}
else if (event.getClass().equals(StatusEvent.class))
{
_o("StatusEvent");
}
else if (event.getClass().equals(UnlinkEvent.class))
{
_o("UnlinkEvent");
}
else if (event.getClass().equals(UserEvent.class))
{
_o("UserEvent");
}
else if (event.getClass().equals(ZapShowChannelsCompleteEvent.class))
{
_o("ZapShowChannelsCompleteEvent");
}
else if (event.getClass().equals(ZapShowChannelsEvent.class))
{
_o("ZapShowChannelsEvent");
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
}
/**
* fires the asterisk events to the GJtapi-Framework
* @param eventType defined in AstTeleEventTypes
* @param call the CallId the event might need
* @param address defines the address and the terminal for the event
* @param cause the cause
*/
protected void fireTelephonyEvent(int eventType, CallId call, String address, int cause)
{
for(Iterator i = listeners.iterator(); i.hasNext(); )
{
TelephonyListener tL = (TelephonyListener)i.next();
switch (eventType)
{
/*case AstTeleEventTypes.addressPrivateData:
tL.addressPrivateData(String address, Serializable data, int cause);
break;*/
case AstTeleEventTypes.callActive:
tL.callActive(call, cause);
break;
case AstTeleEventTypes.callInvalid:
tL.callInvalid(call, cause);
break;
/*case AstTeleEventTypes.callOverloadCeased:
tL.callOverloadCeased(String address);callOverloadEncountered(String address);
break;
case AstTeleEventTypes.callPrivateData:
tL.callPrivateData(CallId call, Serializable data, int cause);
break;
case AstTeleEventTypes.connectionAddressAnalyse:
tL.connectionAddressAnalyse(CallId id, String address, int cause);
break;
case AstTeleEventTypes.connectionAddressCollect:
tL.connectionAddressCollect(CallId id, String address, int cause);
break;*/
case AstTeleEventTypes.connectionAlerting:
tL.connectionAlerting(call, address, cause);
break;
/* case AstTeleEventTypes.connectionAuthorizeCallAttempt:
tL.connectionAuthorizeCallAttempt(CallId id, String address, int cause);
break;
case AstTeleEventTypes.connectionCallDelivery:
tL.connectionCallDelivery(CallId id, String address, int cause);
break;*/
case AstTeleEventTypes.connectionConnected:
tL.connectionConnected(call, address, cause);
break;
case AstTeleEventTypes.connectionDisconnected:
tL.connectionDisconnected(call, address, cause);
break;
case AstTeleEventTypes.connectionFailed:
tL.connectionFailed(call, address, cause);
break;
case AstTeleEventTypes.connectionInProgress:
tL.connectionInProgress(call, address, cause);
break;
/*case AstTeleEventTypes.connectionSuspended:
//tL.connectionSuspended(CallId id, String address, int cause);
break;
case AstTeleEventTypes.mediaPlayPause:
//tL.mediaPlayPause(String terminal, int index, int offset, Symbol trigger);
break;
case AstTeleEventTypes.mediaPlayResume:
//tL.mediaPlayResume(String terminal, Symbol trigger);
break;
case AstTeleEventTypes.mediaRecorderPause:
//tL.mediaRecorderPause(String terminal, int duration, Symbol trigger);
break;
case AstTeleEventTypes.mediaRecorderResume:
//tL.mediaRecorderResume(String terminal, Symbol trigger);
break;
case AstTeleEventTypes.mediaSignalDetectorDetected:
//tL.mediaSignalDetectorDetected(String terminal, Symbol[] sigs);
break;
case AstTeleEventTypes.mediaSignalDetectorOverflow:
//tL.mediaSignalDetectorOverflow(String terminal, Symbol[] sigs);
break;
case AstTeleEventTypes.mediaSignalDetectorPatternMatched:
//tL.mediaSignalDetectorPatternMatched(String terminal, Symbol[] sigs, int index);
break;
case AstTeleEventTypes.providerPrivateData:
//tL.providerPrivateData(Serializable data, int cause);
break; */
case AstTeleEventTypes.terminalConnectionCreated:
tL.terminalConnectionCreated(call, address, address, cause);
break;
case AstTeleEventTypes.terminalConnectionDropped:
tL.terminalConnectionDropped(call, address, address, cause);
break;
case AstTeleEventTypes.terminalConnectionHeld:
tL.terminalConnectionHeld(call, address, address, cause);
break;
case AstTeleEventTypes.terminalConnectionRinging:
tL.terminalConnectionRinging(call, address, address, cause);
break;
case AstTeleEventTypes.terminalConnectionTalking:
tL.terminalConnectionTalking(call, address, address, cause);
break;
/*case AstTeleEventTypes.terminalPrivateData:
tL.terminalPrivateData(String terminal, Serializable data, int cause);*/
default:
break;
}
}
}
/**
* returns the Channel for that uniqueId regardless of a CallId
* @param uniqueId
* @return
*/
private Channel getChannelForUniqueId(String uniqueId)
{
return (Channel)asteriskManager.getChannels().get(uniqueId);
}
/**
* Searches all callIds for this uniqueId.
* @param uniqueId
* @return the callIds as array
*/
private AsteriskCallId[] getCallIdsForUniqueId(String uniqueId)
{
ArrayList arr = new ArrayList();
for(Iterator i = callSet.iterator(); i.hasNext(); )
{
AsteriskCallId next = (AsteriskCallId)i.next();
if(next.getConnections().containsKey(uniqueId))
arr.add(next);
}
return (AsteriskCallId[])arr.toArray(new AsteriskCallId[arr.size()]);
}
/**
* a simple debugging method
* @param out is put to System.out
*/
private void _o(String out)
{
if(OUT)
System.out.println(out);
}
private AsteriskConnectionDetail getDetail(AsteriskCallId call, String uniqueId)
{
return (AsteriskConnectionDetail)call.getConnections().get(uniqueId);
}
/**
* AsteriskConnectionDetail representing the caller
* @param call
* @return
*/
private AsteriskConnectionDetail getCallingDetail(AsteriskCallId call)
{
Collection values = call.getConnections().values();
for(Iterator i = values.iterator(); i.hasNext(); )
{
AsteriskConnectionDetail aDetail = (AsteriskConnectionDetail)i.next();
if(aDetail.address != null && aDetail.calledAddress != null)
return aDetail;
}
return null;
}
private String getAddressForAsteriskCallerId(String callerId)
{
if(addressePrefixes == null)
{
addressePrefixes = new ArrayList();
addressePrefixes.add("");
for(int i = 0; i < addresses.length; i++)
{
String[] splitted = addresses[i].split("/");
if(splitted.length > 1)
if(!addressePrefixes.contains(splitted[0]+"/"))
addressePrefixes.add(splitted[0]+"/");
}
}
for(int i = 0; i < addresses.length; i++)
{
for(Iterator j = addressePrefixes.iterator(); j.hasNext(); )
{
if(addresses[i].equals(j.next().toString() + callerId))
return addresses[i];
}
}
return callerId;
}
private String getAsteriskCallerIdForAddress(String address)
{
int index = address.lastIndexOf('/');
if(index != -1)
return address.substring(index+1);
return address;
}
private boolean isOneOfMyAddresses(String address)
{
for(int i = 0; i < addresses.length; i++)
{
if(addresses[i].equals(address))
return true;
}
return false;
}
private AsteriskConnectionDetail getDetailForCallerId(AsteriskCallId call, String callerId)
{
Collection values = call.getConnections().values();
for(Iterator i = values.iterator(); i.hasNext(); )
{
AsteriskConnectionDetail aDetail = (AsteriskConnectionDetail)i.next();
if(aDetail.address.equals(callerId))
return aDetail;
}
return null;
}
private AsteriskConnectionDetail[] getDetailsForNotCallerId(AsteriskCallId call, String callerId)
{
List aList = new ArrayList();
Collection values = call.getConnections().values();
for(Iterator i = values.iterator(); i.hasNext(); )
{
AsteriskConnectionDetail aDetail = (AsteriskConnectionDetail)i.next();
if(!aDetail.address.equals(callerId))
aList.add(aDetail);
}
AsteriskConnectionDetail[] arr = new AsteriskConnectionDetail[aList.size()];
aList.toArray(arr);
return arr;
}
private String[] adjustCallingCalled(String thisOne, String calling, String called)
{
if(thisOne.equals(calling))
return new String[]{getAddressForAsteriskCallerId(calling), called};
else if(thisOne.equals(called))
return new String[]{calling, getAddressForAsteriskCallerId(called)};
return null;
}
private void hangUpChannel(String channel)
{
HangupAction hangupAction = new HangupAction();
hangupAction.setChannel(channel);
try
{
managerConnection.sendAction(hangupAction);
_o("hangup action sent for " + channel);
}
catch (IOException e)
{
e.printStackTrace();
}
catch (TimeoutException e)
{
e.printStackTrace();
}
}
}