package uk.co.mmscomputing.device.capi; import uk.co.mmscomputing.util.metadata.*; import uk.co.mmscomputing.device.capi.protocol.*; import uk.co.mmscomputing.device.fax.*; import uk.co.mmscomputing.device.phone.*; public class CapiVoicePlugin implements CapiPlugin{ private PhoneAnswerer phoneAnswerer = null; private FaxReceiver faxReceiver = null; public CapiVoicePlugin(){ } public void addListener(PhoneAnswererListener listener){ if(phoneAnswerer==null){phoneAnswerer=new PhoneAnswerer();} phoneAnswerer.addListener(listener); } public void addListener(FaxReceiverListener listener){ if(faxReceiver==null){faxReceiver=new FaxReceiver();} faxReceiver.addListener(listener); } public void update(Object data, Metadata metadata){ // called from CapiServerApplication if(data instanceof CapiMetadata.Indication){ // called from PickUp.indicateCall CapiMetadata.Indication call=(CapiMetadata.Indication)data; if(!call.isAccepted()){ // if another plugin has not yet accepted call try{ if(phoneAnswerer!=null){ call.setPlugin(this); PhoneAnswererMetadata md=new PhoneAnswererMetadata(); md.setController(call.getController()); md.setLocalNo(call.localno); md.setRemoteNo(call.remoteno); md.setState(PhoneConstants.phoneRinging); phoneAnswerer.fireListenerUpdate(md.STATE,md); // tell application about state change int pickuptime=md.getPickUpTime(); if(pickuptime>=0){ call.setAccept(pickuptime*1000,md.getBlocker()); // accept call // call.setProtocol(new SpeechProtocol()); // SpeechProtocol is default; No need for this; } } }catch(Exception e){ System.out.println("9\b"+getClass().getName()+".update\n\t"+e); System.err.println(getClass().getName()+".update\n\t"+e); e.printStackTrace(); } } if(!call.isAccepted()){ // if another plugin has not yet accepted call try{ if(faxReceiver!=null){ call.setPlugin(this); FaxReceiverMetadata md=new FaxReceiverMetadata(); md.setLocalNo(call.localno); md.setRemoteNo(call.remoteno); md.setState(FaxConstants.faxRinging); faxReceiver.fireListenerUpdate(md.STATE,md); // tell application about state change int pickuptime=md.getPickUpTime(); String header=md.getHeader(); String local=md.getLocalNo(); if(pickuptime>=0){ call.setAccept(pickuptime*1000,md.getBlocker()); // accept call call.setProtocol(new FaxBProtocol(0,0,local,header));// answer as fax } } }catch(Exception e){ System.out.println("9\b"+getClass().getName()+".update\n\t"+e); System.err.println(getClass().getName()+".update\n\t"+e); e.printStackTrace(); } } } } public void serve(CapiChannel channel){ // from CapiSystem BProtocol protocol=channel.getProtocol(); if(protocol instanceof SpeechProtocol){ // if speech then call handler if(faxReceiver!=null){ new CapiFaxDetector(channel).start(); // start fax detection } new VoiceThread(channel).start(); }else if(protocol instanceof FaxBProtocol){ // if fax then call fax handler new FaxThread(channel).start(); }else{ // this shouldn't happen! System.out.println("3\b"+getClass().getName()+".serve:\n\tUnknown Protocol."); try{ channel.close(); }catch(Exception e){ System.out.println("3\b"+getClass().getName()+".serve:\n\t"+e); } } } private class VoiceThread extends Thread{ CapiChannel channel; PhoneCallHandler pch; VoiceThread(CapiChannel channel){ this.channel=channel; pch=null; } public void run(){ try{ PhoneAnswererMetadata md=new PhoneAnswererMetadata(); md.setState(PhoneConstants.phoneConnected); phoneAnswerer.fireListenerUpdate(md.STATE,md); // tell application accepted call pch=md.getHandler(); // get a phone call handler // channel.put(new EchoCancellerReq.GetSupportedServicesReq(channel.getApplID(),channel.getLineID())); pch.run( channel.getLocalNo(), channel.getRemoteNo(), channel.getPCMInputStream(), channel.getPCMOutputStream() ); md.setHandler(pch); md.setChangedProtocol(channel.getChangedProtocol()); md.setState(PhoneConstants.phoneDisconnected); phoneAnswerer.fireListenerUpdate(md.STATE,md); // tell app we are done }catch(Exception e){ System.out.println("9\b"+getClass().getName()+".run\n\tDisconnected call.\n\t"+e); System.err.println(getClass().getName()+".run\n\tDisconnected call.\n\t"+e); e.printStackTrace(); }finally{ try{ channel.close(); }catch(Exception ioe){ System.out.println("3\b"+getClass().getName()+".run:\n\t"+ioe); } } } } private class FaxThread extends Thread{ CapiChannel channel; public FaxThread(CapiChannel channel){ this.channel=channel; } public void run(){ try{ FaxReceiverMetadata md=new FaxReceiverMetadata(); md.setState(FaxConstants.faxConnected); faxReceiver.fireListenerUpdate(md.STATE,md); // tell application accepted call FaxCallHandler fch=md.getHandler(); // get a fax call handler fch.run( channel.getLocalNo(), channel.getRemoteNo(), channel.getInputStream(), channel.getOutputStream() ); md.setHandler(fch); md.setState(FaxConstants.faxDisconnected); faxReceiver.fireListenerUpdate(md.STATE,md); // tell app we are done }catch(Exception e){ System.out.println("9\b"+getClass().getName()+".run\n\tDisconnected call.\n\t"+e); e.printStackTrace(); }finally{ try{ channel.close(); }catch(Exception ioe){System.out.println(getClass().getName()+".run:\n\t"+ioe); System.out.println("3\b"+getClass().getName()+".run:\n\t"+ioe); } } } } static private CapiVoicePlugin defaultPlugin=null; static public CapiVoicePlugin getDefaultPlugin(){ if(defaultPlugin!=null){return defaultPlugin;} try{ String osname=System.getProperty("os.name"); if(osname.startsWith("Linux") || osname.startsWith("Windows")){ defaultPlugin=new CapiVoicePlugin(); CapiSystem.getSystem().addPlugin(defaultPlugin); }else{ System.out.println("9\buk.co.mmscomputing.device.capi.CapiVoicePlugin.getDevice:\n\tUnsupported Operating System."); } }catch(Exception e){ e.printStackTrace(); System.out.println("9\buk.co.mmscomputing.device.capi.CapiVoicePlugin.getDevice:\n\tCould not open CapiVoicePlugin\n\t"+e); } return defaultPlugin; } }