package uk.co.mmscomputing.device.capi.samples; import java.io.*; import uk.co.mmscomputing.device.capi.*; import uk.co.mmscomputing.device.capi.man.avm.*; import uk.co.mmscomputing.device.capi.q931.*; // http://www.avm.de/ftp/developer/index.html [2006-09-10] // dtrace32 uses following manufacturer messages. (Used capiktrc to trace message flow) public class AVMDChannelTracer implements Runnable{ private boolean running=false; protected int appid=-1; protected int lineid=1; public AVMDChannelTracer()throws IOException{ jcapi.checkInstalled(); appid=jcapi.register(1,2,128); } private void put(MsgOut msg)throws IOException{ jcapi.putMessage(appid,msg.getBytes()); } static public final int RR = 0x01; // Receiver Ready static public final int RNR = 0x05; // Receiver Not Ready static public final int REJ = 0x09; // Reject static public final int SABME = 0x6f; // Set Asynchronous Balanced Mode Extended static public final int DM = 0x0f; // Disconnect Mode static public final int UI = 0x03; // Unnumbered Information static public final int DISC = 0x43; // Disconnect static public final int UA = 0x63; // Unnumbered Acknowledgement static public final int FRMR = 0x87; // Frame Reject static public final int XID = 0xaf; // Exchange Identification protected void handleMessage(MsgIn msg)throws IOException{ if(msg instanceof AVMDTraceInd){ AVMDTraceInd avmmsg=(AVMDTraceInd)msg; put(new AVMResp(appid,lineid,avmmsg.getClassId(),avmmsg.getFunctionId(),StructOut.empty)); byte[] ddata = avmmsg.getBytes(); Rider r=new Rider(ddata); System.out.println(r.toString()); // only avm specific data r.read();r.read(); // not quite sure what these bytes are for // D-channel layer 2: lapd/Q.921 /* 8 7 6 5 4 3 2 1 2 SAPI |C/R| 0 Address Field 3 TEI | 1 Control Field 4 N(S) | 0 (I)nformation Format 5 N(R) | P OR 4 0 | 0 | 0 | 0 | s | s | 0 | 1 (S)upervisory Format 5 N(R) |P/F OR 4 M | M | M |P/F| M | M | 1 | 1 (U)nnumbered Format P = poll; requires an immediate response (primary station) / F = final frame in response (secondary station) SAPI 0 Frame is transporting signaling information 1 Frame is carrying data for the Q.931 packet mode data 16 Frame is carrying data for the X.25 packet-mode data 62 Frame for test or recovery 63 Frame is used for management purpose TEI 0 - 63 Manually allocated TEI values 64 -126 Automatically allocated TEI values 127 Broadcasting */ int sapi=r.read(); int crbit=(sapi>>1)&0x01; // command/response bit: from user=0 OR from network=1 means command, otherwise response sapi>>=2; int tei=r.read(); tei>>=1; int ctl=r.read(); int pf,nr=0,ns=0; if((ctl&0x03)==0x03){ // U-Format (4 bytes) pf = ctl & 0x10; ctl = ctl & ~0x10; }else{ // I- & S-Format (5 bytes) nr=r.read(); pf = nr&0x01; nr>>=1; } System.out.println("lapd: cr="+crbit+" sapi="+sapi+" tei="+tei+" ctl=0x"+Integer.toHexString(ctl)+" pf="+pf); switch(sapi){ case 0 : System.out.println(" Frame is transporting signaling information "); break; case 1 : System.out.println(" Frame is carrying data for the Q.931 packet mode data "); break; case 16: System.out.println(" Frame is carrying data for the X.25 packet-mode data "); break; case 62: System.out.println(" Frame for test or recovery "); break; case 63: System.out.println(" Frame is used for management purpose "); break; } switch(ctl){ case RR: System.out.println(" RR - Receiver Ready nr="+nr); break; // S-Format case RNR: System.out.println(" RNR - Receiver Not Ready nr="+nr); break; case REJ: System.out.println(" REJ - Reject nr="+nr); break; case SABME: System.out.println(" SABME - Set Asynchronous Balanced Mode Extended "); break; // U-Format case DM: System.out.println(" DM - Disconnect Mode "); break; case UI: System.out.println(" UI - Unnumbered Information "); break; case DISC: System.out.println(" DISC - Disconnect "); break; case UA: System.out.println(" UA - Unnumbered Acknowledgement "); break; case FRMR: System.out.println(" FRMR - Frame Reject "); break; case XID: System.out.println(" XID - Exchange Identification "); break; } if((ctl&0x01)==0){ // I-Format ns=ctl>>1; System.out.println(" Information Format nr="+nr+" ns="+ns); } try{ Q931Message qmsg=Q931Message.create(r); // D-channel layer 3: Q.931 System.out.println(qmsg.toString()); }catch(IndexOutOfBoundsException ioobe){ }catch(Exception e){ e.printStackTrace(); } }else{ System.out.println(msg); } } byte[] buf=null; public void run(){ running=true; try{ put(new AVMDTraceReq.Start(appid,lineid)); // start tracing D-Channel information while(running){ jcapi.waitForMessage(appid); // block until message arrives buf=jcapi.getMessage(appid,buf); MsgIn msg=MsgIn.create(buf); // turn byte array into java MsgIn object handleMessage(msg); } put(new AVMDTraceReq.Stop(appid,lineid)); // stop tracing D-Channel information jcapi.waitForMessage(appid); }catch(IOException ioe){ System.err.println(ioe.getMessage()); }finally{ try{ jcapi.release(appid); }catch(IOException ioe){ System.err.println(ioe.getMessage()); } } } public static void main(String[] argv){ try{ AVMDChannelTracer tracer=new AVMDChannelTracer(); new Thread(tracer).start(); }catch(Exception e){ System.err.println(e.getMessage()); } } }