package uk.co.mmscomputing.device.capi; import java.io.*; import uk.co.mmscomputing.concurrent.*; import uk.co.mmscomputing.device.capi.ncc.*; import uk.co.mmscomputing.device.capi.exception.*; public class CapiNCC extends CapiChannel{ protected CapiInputStream in; protected CapiOutputStream out; private boolean outgoing; private int reason = -1; private Semaphore ds = new Semaphore(0,true); CapiNCC(CapiApplication appl,ConnectB3Conf msg){ // outgoing call super(appl,msg.lineid); outgoing=true; in =new CapiInputStream(this); out=new CapiOutputStream(this); } CapiNCC(CapiApplication appl,ConnectB3Ind msg){ // incoming call super(appl,msg.lineid); outgoing=false; in =new CapiInputStream(this); out=new CapiOutputStream(this); } boolean isOutgoing(){ return outgoing;} boolean isIncoming(){ return !outgoing;} void received(ConnectB3ActiveInd msg){ if(checkIsNotConnected()){ } } void received(DataB3Ind msg)throws CapiException{ if(isConnected()){ in.received(msg); }else{ appl.put(new DataB3Resp(msg.appid,msg.lineid,msg.getHandle())); } } void sendDataResp(DataB3Resp msg)throws CapiException{ // called from CapiInputStream when DataB3Ind has been processed appl.put(msg); } void received(DataB3Conf msg)throws CapiException{ out.received(msg); } void disconnect(int r)throws CapiException{ // call only from CapiApplication thread reason=(r==0)?0x3410:r; checkIsNotDisconnected(); // passive disconnect initiated by peer in.disconnect(); // close input & ouput stream out.disconnect(); // and waste data if any in output queue ds.release(); // release disconnect semaphore } int getDisconnectReason(){return reason;} void received(DisconnectB3Ind msg)throws CapiException{ // cannot send anything anymore reason=msg.getReason(); disconnect(reason); } void selectFaxProtocol()throws CapiException{ appl.getPLC(lineid&0x0000FFFF).selectFaxProtocol(); } // Input or Output Thread calls public CapiInputStream getInputStream()throws IOException{return in;} public CapiOutputStream getOutputStream()throws IOException{return out;} DataB3Req write(int handle, byte[] b, int len)throws IOException{ DataB3Req req=new DataB3Req(applid,lineid,handle,0x00,b,len); appl.put(req); return req; } private void activeDisconnect()throws CapiException{ if(checkIsNotDisconnected()){ // if not disconnected yet appl.put(new DisconnectB3Req(applid,lineid)); // send DisconnectB3Req and } try{ds.acquire();}catch(InterruptedException ie){} // wait for DisconnectB3Ind ds.release(); // release other threads } void closedInput()throws IOException{ // called from CapiInputStream if(out.isOpen()){return;} activeDisconnect(); // application closed both streams now } void closedOutput()throws IOException{ // called from CapiOutputStream if(in.isOpen()){return;} activeDisconnect(); // application closed both streams now } public void close()throws IOException{ // do not call from CapiApplication thread if(checkIsOpen()){ in.close(); out.close(); // wait until all DataB3Conf come in } } }