13 | * 1 2 3 14 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 15 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 16 | * |F| Source call number | time-stamp | 17 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 18 | * | | 19 | * : Data : 20 | * | | 21 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 22 | *23 | */ 24 | public class MiniFrame extends Frame { 25 | 26 | 27 | private ByteBuffer _buff; 28 | 29 | 30 | /** 31 | * The outbound constructor. 32 | * 33 | * @param call The Call object 34 | */ 35 | public MiniFrame(Call call) { 36 | _call = call; 37 | _fullBit = false; 38 | } 39 | 40 | 41 | /** 42 | * The inbound constructor. 43 | * 44 | * @param call The Call object 45 | * @param bs The incoming message bytes 46 | * @throws IllegalArgumentException The bytes do not represent a 47 | * miniframe 48 | */ 49 | public MiniFrame(Call call, byte[] bs) 50 | throws IllegalArgumentException { 51 | ByteBuffer buf = ByteBuffer.wrap(bs); 52 | _sCall = buf.getShort(); 53 | if (_sCall < 0) { 54 | _sCall = 0x7fff & _sCall; 55 | _fullBit = true; 56 | throw new IllegalArgumentException("Not a miniframe, but fullframe."); 57 | } else { 58 | _fullBit = false; 59 | } 60 | setTimestampVal(buf.getChar()); 61 | _data = buf.slice(); 62 | _call = call; 63 | } 64 | 65 | 66 | /** 67 | * ack is called to send any required response. This method is 68 | * empty. 69 | */ 70 | @Override 71 | void ack() { 72 | } 73 | 74 | 75 | /** 76 | * Sends a specified buffer. The buffer represents the Data field in 77 | * the frame. If sets the header fields and calls sendMe() that will 78 | * do the actual sending. 79 | * 80 | * @param buff The buff (data) 81 | * @see #sendMe() 82 | */ 83 | public void sendMe(byte[] buff) { 84 | _buff = ByteBuffer.allocate(buff.length + 4); 85 | _buff.putChar((char) _sCall); 86 | _buff.putChar((char) (0xffff & getTimestampVal())); 87 | _buff.put(buff); 88 | sendMe(); 89 | } 90 | 91 | 92 | /** 93 | * used by data suppliers for outbound messages... put your data 94 | * on the end of this... 95 | * 96 | * @return ByteBuffer 97 | */ 98 | ByteBuffer getBuffer() { 99 | return _buff; 100 | } 101 | 102 | 103 | /** 104 | * arrived is called when a packet arrives. 105 | * 106 | * @throws IAX2ProtocolException 107 | */ 108 | @Override 109 | void arrived() throws IAX2ProtocolException { 110 | int fsz = _call.getFrameSz(); 111 | byte[] bs = new byte[fsz]; 112 | long ts = this.getTimestampVal(); 113 | int dr = _data.remaining(); 114 | if (dr < fsz) { 115 | Log.warn("buffer too short: " + dr + " not " + fsz); 116 | } else { 117 | _data.get(bs); 118 | try { 119 | _call.audioWrite(bs, ts); 120 | } catch (IOException ex) { 121 | Log.warn(ex.getMessage()); 122 | } 123 | } 124 | Log.verb("got minframe " + ts); 125 | } 126 | 127 | 128 | /** 129 | * Sends this frame. 130 | * 131 | * @see #sendMe(byte[]) 132 | * @see Call#send(ByteBuffer) 133 | */ 134 | void sendMe() { 135 | _call.send(_buff); 136 | } 137 | 138 | } 139 | 140 | -------------------------------------------------------------------------------- /src/main/java/org/asteriskjava/iax/protocol/ProtocolControlFrameNew.java: -------------------------------------------------------------------------------- 1 | 2 | package org.asteriskjava.iax.protocol; 3 | 4 | 5 | import org.asteriskjava.iax.audio.javasound.AudioInterface; 6 | 7 | /** 8 | * Special cases for outbound 'New' messages. 9 | */ 10 | class ProtocolControlFrameNew extends ProtocolControlFrame { 11 | 12 | 13 | /** 14 | * The outbound constructor. This sets the destination call number 15 | * to zero. 16 | * 17 | * @param p0 The Call object 18 | */ 19 | public ProtocolControlFrameNew(Call p0) { 20 | super(p0); 21 | _dCall = 0; 22 | _subclass = ProtocolControlFrameNew.NEW; 23 | this.setTimestampVal(0); 24 | _call.resetClock(); 25 | } 26 | 27 | 28 | /** 29 | * The inbound constructor. 30 | * 31 | * @param p0 The Call object 32 | * @param p1 The incoming message bytes 33 | */ 34 | public ProtocolControlFrameNew(Call p0, byte[] p1) { 35 | super(p0, p1); 36 | } 37 | 38 | 39 | /** 40 | * Returns if this is a NEW message. True by default. 41 | * 42 | * @return true if NEW, false otherwise 43 | */ 44 | @Override 45 | public boolean isANew() { 46 | return true; 47 | } 48 | 49 | 50 | /** 51 | * Sends this NEW message. 52 | * 53 | * @param cno The source call number 54 | * @param username The username (sent in IE) 55 | * @param calledNo The number we're calling (sent in IE) 56 | * @param callingNo Number/extension we call from (sent in IE) 57 | * @param callingName Name of the person calling (sent in IE) 58 | */ 59 | /* 60 | IE that can be sent: 61 | - 8.6.1. CALLED NUMBER 62 | - 8.6.2. CALLING NUMBER 63 | - 8.6.3. CALLING ANI 64 | - 8.6.4. CALLING NAME 65 | - 8.6.5. CALLED CONTEXT 66 | - 8.6.6. USERNAME 67 | - 8.6.8. CAPABILITY 68 | - 8.6.9. FORMAT 69 | - 8.6.10. LANGUAGE 70 | - 8.6.11. VERSION (MUST, and should be first) 71 | - 8.6.12. ADSICPE 72 | - 8.6.13. DNID 73 | - 8.6.25. AUTOANSWER 74 | - 8.6.31. DATETIME 75 | - 8.6.38. CALLINGPRES 76 | - 8.6.39. CALLINGTON 77 | - 8.6.43. ENCRYPTION 78 | - 8.6.45. CODEC PREFS 79 | */ 80 | public void sendNew(Character cno, String username, String calledNo, 81 | String callingNo, String callingName) { 82 | 83 | Log.debug("ProtocolControlFrameNew.sendNew: calledNo=" + calledNo 84 | + ", callingNo=" + callingNo 85 | + ", callingName=" + callingName 86 | + ", username=" + username); 87 | _sCall = cno.charValue(); 88 | _iseq = _call.getIseq(); 89 | _oseq = _call.getOseqInc(); 90 | 91 | InfoElement ie = new InfoElement(); 92 | ie.calledNo = calledNo; 93 | ie.callingNo = callingNo; 94 | ie.callingName = callingName; 95 | ie.username = username; 96 | AudioInterface a = _call.getAudioFace(); 97 | int format = a.supportedCodecs().intValue(); 98 | ie.format = VoiceFrame.GSM_BIT; 99 | ie.version = Integer.valueOf(2); 100 | ie.codec_prefs = a.codecPrefString().getBytes(); 101 | ie.capability = Integer.valueOf(format); 102 | // ie.putIaxVar("foobar","724024"); 103 | Log.debug("Sending initial NEW"); 104 | sendMe(ie); 105 | } 106 | 107 | 108 | /** 109 | * Commit this frame. This method is called when the NEW frame we sent 110 | * has been acked. This will call Call.gotAckToNew() 111 | * 112 | * @param ack The ack frame 113 | * @see Call#gotAckToNew(FullFrame) 114 | */ 115 | @Override 116 | void commit(FullFrame ack) { 117 | if (this._call != null) { 118 | _call.gotAckToNew(ack); 119 | } 120 | Log.debug("Commit on new called"); 121 | } 122 | 123 | } 124 | 125 | -------------------------------------------------------------------------------- /src/main/java/org/asteriskjava/iax/protocol/ProtocolEventListener.java: -------------------------------------------------------------------------------- 1 | 2 | package org.asteriskjava.iax.protocol; 3 | 4 | /** 5 | * Minimal events sent by the protocol engine. 6 | */ 7 | public interface ProtocolEventListener { 8 | public void newCall(Call c); 9 | 10 | public void registered(Friend f, boolean s); 11 | 12 | public void hungUp(Call c); 13 | 14 | public void ringing(Call c); 15 | 16 | public void answered(Call c); 17 | 18 | public void setHostReachable(Friend f, boolean b, int roundtrip); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/main/java/org/asteriskjava/iax/protocol/Ringer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Benaiad@gmail.com 4 | */ 5 | package org.asteriskjava.iax.protocol; 6 | 7 | import javax.sound.sampled.*; 8 | import java.io.IOException; 9 | 10 | public class Ringer implements Runnable { 11 | 12 | String fileLocation = "ring.wav"; 13 | boolean stop = false; 14 | 15 | Ringer() { 16 | } 17 | 18 | public void start() { 19 | stop = false; 20 | Thread t = new Thread(this); 21 | t.start(); 22 | } 23 | 24 | public void run() { 25 | while (!stop) { 26 | playSound(fileLocation); 27 | try { 28 | Thread.sleep(1000); 29 | } catch (InterruptedException ex) { 30 | ; 31 | } 32 | } 33 | } 34 | 35 | public void stop() { 36 | stop = true; 37 | } 38 | 39 | private void playSound(String fileName) { 40 | //File soundFile = new File(fileName); 41 | AudioInputStream audioInputStream = null; 42 | try { 43 | audioInputStream = AudioSystem.getAudioInputStream(getClass().getResourceAsStream(fileName)); 44 | } catch (Exception e) { 45 | e.printStackTrace(); 46 | } 47 | AudioFormat audioFormat = audioInputStream.getFormat(); 48 | SourceDataLine line = null; 49 | DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat); 50 | try { 51 | line = (SourceDataLine) AudioSystem.getLine(info); 52 | line.open(audioFormat); 53 | } catch (LineUnavailableException e) { 54 | e.printStackTrace(); 55 | } catch (Exception e) { 56 | e.printStackTrace(); 57 | } 58 | line.start(); 59 | int nBytesRead = 0; 60 | byte[] abData = new byte[128000]; 61 | 62 | while (nBytesRead != -1 && !stop) { 63 | try { 64 | nBytesRead = audioInputStream.read(abData, 0, abData.length); 65 | } catch (IOException e) { 66 | e.printStackTrace(); 67 | } 68 | if (nBytesRead >= 0) { 69 | int nBytesWritten = line.write(abData, 0, nBytesRead); 70 | } 71 | } 72 | 73 | line.drain(); 74 | line.close(); 75 | } 76 | } -------------------------------------------------------------------------------- /src/main/java/org/asteriskjava/iax/protocol/VoiceFrame.java: -------------------------------------------------------------------------------- 1 | 2 | package org.asteriskjava.iax.protocol; 3 | 4 | import java.io.IOException; 5 | 6 | /** 7 | * VoiceFrame - The frame carries voice data. 8 | */ 9 | public class VoiceFrame extends FullFrame { 10 | 11 | 12 | /** 13 | * G.723.1 index 14 | */ 15 | public final static int G723_NO = 0; 16 | /** 17 | * Constant: G.723.1 - 4, 20, and 24 byte frames of 240 samples 18 | */ 19 | public final static int G723_BIT = 1 << G723_NO; 20 | 21 | /** 22 | * GSM Full Rate index 23 | */ 24 | public final static int GSM_NO = 1; 25 | /** 26 | * Constant: GSM Full Rate - 33 byte chunks of 160 samples or 65 byte chunks of 320 samples 27 | */ 28 | public final static int GSM_BIT = 1 << GSM_NO; 29 | 30 | /** 31 | * G.711 mu-law index 32 | */ 33 | public final static int ULAW_NO = 2; 34 | /** 35 | * Constant: G.711 mu-law - 1 byte per sample 36 | */ 37 | public final static int ULAW_BIT = 1 << ULAW_NO; 38 | 39 | /** 40 | * G.711 a-law index 41 | */ 42 | public final static int ALAW_NO = 3; 43 | /** 44 | * Constant: G.711 a-law - 1 byte per sample 45 | */ 46 | public final static int ALAW_BIT = 1 << ALAW_NO; 47 | 48 | /** 49 | * G.726 index 50 | */ 51 | public final static int G726_NO = 4; 52 | /** 53 | * Constant: G.726 54 | */ 55 | public final static int G726_BIT = 1 << G726_NO; 56 | 57 | /** 58 | * IMA ADPCM index 59 | */ 60 | public final static int ADPCM_NO = 5; 61 | /** 62 | * Constant: IMA ADPCM - 1 byte per 2 samples 63 | */ 64 | public final static int ADPCM_BIT = 1 << ADPCM_NO; 65 | 66 | /** 67 | * 16-bit linear little-endian index 68 | */ 69 | public final static int LIN16_NO = 6; 70 | /** 71 | * Constant: 16-bit linear little-endian - 2 bytes per sample 72 | */ 73 | public final static int LIN16_BIT = 1 << LIN16_NO; 74 | 75 | /** 76 | * LPC10 index 77 | */ 78 | public final static int LPC10_NO = 7; 79 | /** 80 | * Constant: LPC10 - Variable size frame of 172 samples 81 | */ 82 | public final static int LPC10_BIT = 1 << LPC10_NO; 83 | 84 | /** 85 | * G.729 index 86 | */ 87 | public final static int G729_NO = 8; 88 | /** 89 | * Constant: G.729 - 20 bytes chunks of 172 samples 90 | */ 91 | public final static int G729_BIT = 1 << G729_NO; 92 | 93 | /** 94 | * Speex index 95 | */ 96 | public final static int SPEEX_NO = 9; 97 | /** 98 | * Constant: Speex - Variable 99 | */ 100 | public final static int SPEEX_BIT = 1 << SPEEX_NO; 101 | 102 | /** 103 | * ILBC index 104 | */ 105 | public final static int ILBC_NO = 10; 106 | /** 107 | * Constant: ILBC - 50 bytes per 240 samples 108 | */ 109 | public final static int ILBC_BIT = 1 << ILBC_NO; 110 | 111 | /** 112 | * AMR narrowband index - not standardized. 113 | */ 114 | public final static int AMRN_NO = 14; 115 | 116 | public final static int AMRN_BIT = 1 << AMRN_NO; 117 | 118 | 119 | /** 120 | * JPEG index 121 | */ 122 | public final static int JPEG_NO = 16; 123 | /** 124 | * Constant: JPEG 125 | */ 126 | public final static int JPEG_BIT = 1 << JPEG_NO; 127 | 128 | /** 129 | * PNG index 130 | */ 131 | public final static int PNG_NO = 17; 132 | /** 133 | * Constant: PNG 134 | */ 135 | public final static int PNG_BIT = 1 << PNG_NO; 136 | 137 | /** 138 | * H261 index 139 | */ 140 | public final static int H261_NO = 18; 141 | /** 142 | * Constant: H261 143 | */ 144 | public final static int H261_BIT = 1 << H261_NO; 145 | 146 | /** 147 | * H263 index 148 | */ 149 | public final static int H263_NO = 19; 150 | /** 151 | * Constant: H263 152 | */ 153 | public final static int H263_BIT = 1 << H263_NO; 154 | 155 | /** 156 | * H263P index 157 | */ 158 | public final static int H263P_NO = 20; 159 | /** 160 | * Constant: H263P 161 | */ 162 | public final static int H263P_BIT = 1 << H263P_NO; 163 | 164 | 165 | /** 166 | * The outbound constructor. 167 | * 168 | * @param p0 The Call object 169 | */ 170 | public VoiceFrame(Call p0) { 171 | super(p0); 172 | _retry = false; 173 | _frametype = FullFrame.VOICE; 174 | } 175 | 176 | /** 177 | * The inbound constructor. 178 | * 179 | * @param p0 The Call object 180 | * @param p1 The incoming message bytes 181 | */ 182 | public VoiceFrame(Call p0, byte[] p1) { 183 | super(p0, p1); 184 | } 185 | 186 | 187 | /** 188 | * ack is called to send any required response. 189 | */ 190 | @Override 191 | void ack() { 192 | log("got"); 193 | switch (_subclass) { 194 | case GSM_BIT: 195 | case ULAW_BIT: 196 | case ALAW_BIT: 197 | case LIN16_BIT: 198 | case AMRN_BIT: 199 | sendAck(); 200 | break; 201 | default: 202 | Log.warn("Got unwanted Audio format " + _subclass); 203 | break; 204 | } 205 | } 206 | 207 | 208 | /** 209 | * Logs this frame. 210 | * 211 | * @param inout Additional text to log 212 | */ 213 | @Override 214 | protected void log(String inout) { 215 | super.log(inout + " voice frame"); 216 | } 217 | 218 | 219 | /** 220 | * arrived is called when a packet arrives. 221 | * 222 | * @throws IAX2ProtocolException 223 | */ 224 | @Override 225 | void arrived() throws IAX2ProtocolException { 226 | int fsz = _call.getFrameSz(); 227 | byte[] bs = new byte[fsz]; 228 | _data.get(bs); 229 | try { 230 | _call.fullVoiceFrameRcvd(this.getTimestampVal()); 231 | _call.audioWrite(bs, this.getTimestampVal() & 0xffff); 232 | } catch (IOException ex) { 233 | Log.warn(ex.getMessage()); 234 | } 235 | } 236 | 237 | } 238 | 239 | -------------------------------------------------------------------------------- /src/main/java/org/asteriskjava/iax/protocol/ring.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asterisk-java/asterisk-java-iax/27b63e2b307262eecba7fe98c62a42def799c2c2/src/main/java/org/asteriskjava/iax/protocol/ring.wav -------------------------------------------------------------------------------- /src/main/java/org/asteriskjava/iax/ui/BeanCanApplet.java: -------------------------------------------------------------------------------- 1 | 2 | package org.asteriskjava.iax.ui; 3 | 4 | import java.applet.Applet; 5 | 6 | 7 | public class BeanCanApplet extends Applet { 8 | 9 | 10 | String host = "192.168.99.254"; 11 | String user = "2001"; 12 | String pass = "1234"; 13 | 14 | 15 | Integer debug = 0; 16 | BeanCanFrameManager bcf; 17 | 18 | 19 | //Construct the applet 20 | public BeanCanApplet() { 21 | 22 | } 23 | 24 | //Initialize the applet 25 | @Override 26 | public void init() { 27 | 28 | try { 29 | jbInit(); 30 | } catch (Exception e) { 31 | e.printStackTrace(); 32 | } 33 | } 34 | 35 | //Component initialization 36 | private void jbInit() throws Exception { 37 | bcf = new BeanCanFrameManager(true, debug.intValue(), host); 38 | bcf.validate(); 39 | 40 | 41 | } 42 | 43 | //Start the applet 44 | @Override 45 | public void start() { 46 | 47 | if (bcf != null) { 48 | bcf.set_host(host); 49 | bcf.set_username(user); 50 | bcf.set_password(pass); 51 | bcf.set_debug(debug.intValue()); 52 | bcf.start(); 53 | bcf.register(); 54 | 55 | 56 | } 57 | } 58 | 59 | 60 | //Stop the applet 61 | @Override 62 | public void stop() { 63 | if (bcf != null) { 64 | bcf.stop(); 65 | } 66 | } 67 | 68 | //Destroy the applet 69 | @Override 70 | public void destroy() { 71 | 72 | if (bcf != null) { 73 | bcf.stop(); 74 | } 75 | 76 | } 77 | 78 | //Get Applet information 79 | @Override 80 | public String getAppletInfo() { 81 | return "Integra CCS"; 82 | } 83 | 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/org/asteriskjava/iax/ui/BeanCanFrame.java: -------------------------------------------------------------------------------- 1 | 2 | package org.asteriskjava.iax.ui; 3 | 4 | 5 | import org.asteriskjava.iax.util.DTMFGenerator; 6 | 7 | import javax.swing.*; 8 | import java.awt.*; 9 | import java.awt.event.ActionEvent; 10 | import java.awt.event.WindowEvent; 11 | 12 | 13 | public class BeanCanFrame extends JFrame { 14 | 15 | JPanel contentPane; 16 | JMenuBar jMenuBar1 = new JMenuBar(); 17 | JMenu jMenuFile = new JMenu(); 18 | JMenuItem jMenuFileExit = new JMenuItem(); 19 | JMenu jMenuHelp = new JMenu(); 20 | JMenuItem jMenuHelpAbout = new JMenuItem(); 21 | BorderLayout borderLayout1 = new BorderLayout(); 22 | JPanel jPanel1 = new JPanel(); 23 | JPanel jPanel2 = new JPanel(); 24 | JPanel jPanel3 = new JPanel(); 25 | JPanel jPanel4 = new JPanel(); 26 | BorderLayout borderLayout2 = new BorderLayout(); 27 | JTextField dialString = new JTextField(); 28 | GridLayout gridLayout1 = new GridLayout(); 29 | JButton jButton1 = new JButton(); 30 | JButton jButton2 = new JButton(); 31 | JButton jButton3 = new JButton(); 32 | JButton jButton4 = new JButton(); 33 | JButton jButton5 = new JButton(); 34 | JButton jButton6 = new JButton(); 35 | JButton jButton7 = new JButton(); 36 | JButton jButton8 = new JButton(); 37 | JButton jButton9 = new JButton(); 38 | JButton jButton0 = new JButton(); 39 | JButton jButton11 = new JButton(); 40 | JButton jButton12 = new JButton(); 41 | BorderLayout borderLayout3 = new BorderLayout(); 42 | JLabel status = new JLabel(); 43 | JButton act = new JButton(); 44 | JButton clear = new JButton(); 45 | JPanel jPanel5 = new JPanel(); 46 | GridLayout gridLayout2 = new GridLayout(); 47 | JPanel jPanel6 = new JPanel(); 48 | JPanel jPanel7 = new JPanel(); 49 | BorderLayout borderLayout4 = new BorderLayout(); 50 | BorderLayout borderLayout5 = new BorderLayout(); 51 | BorderLayout borderLayout6 = new BorderLayout(); 52 | 53 | //Construct the frame 54 | public BeanCanFrame() { 55 | enableEvents(AWTEvent.WINDOW_EVENT_MASK); 56 | try { 57 | jbInit(); 58 | } catch (Exception e) { 59 | e.printStackTrace(); 60 | } 61 | } 62 | 63 | //Component initialization 64 | private void jbInit() throws Exception { 65 | contentPane = (JPanel) this.getContentPane(); 66 | contentPane.setLayout(borderLayout1); 67 | this.setSize(new Dimension(300, 200)); 68 | this.setTitle("Integra CCS IaxJphone"); 69 | this.setAlwaysOnTop(true); 70 | 71 | jPanel1.setLayout(borderLayout2); 72 | dialString.setText(""); 73 | dialString.addActionListener(new BeanCanFrame_dialString_actionAdapter(this)); 74 | jPanel3.setLayout(gridLayout1); 75 | gridLayout1.setColumns(3); 76 | gridLayout1.setRows(4); 77 | jButton1.setMnemonic('1'); 78 | jButton1.setText("1"); 79 | jButton1.addActionListener(new BeanCanFrame_jButton1_actionAdapter(this)); 80 | jButton2.setMnemonic('2'); 81 | jButton2.setText("2"); 82 | jButton2.addActionListener(new BeanCanFrame_jButton2_actionAdapter(this)); 83 | jButton3.setMnemonic('3'); 84 | jButton3.setText("3"); 85 | jButton3.addActionListener(new BeanCanFrame_jButton3_actionAdapter(this)); 86 | jButton4.setText("4"); 87 | jButton4.addActionListener(new BeanCanFrame_jButton4_actionAdapter(this)); 88 | jButton5.setText("5"); 89 | jButton5.addActionListener(new BeanCanFrame_jButton5_actionAdapter(this)); 90 | jButton6.setText("6"); 91 | jButton6.addActionListener(new BeanCanFrame_jButton6_actionAdapter(this)); 92 | jButton7.setText("7"); 93 | jButton7.addActionListener(new BeanCanFrame_jButton7_actionAdapter(this)); 94 | jButton8.setText("8"); 95 | jButton8.addActionListener(new BeanCanFrame_jButton8_actionAdapter(this)); 96 | jButton9.setText("9"); 97 | jButton9.addActionListener(new BeanCanFrame_jButton9_actionAdapter(this)); 98 | jButton0.setText("0"); 99 | jButton0.addActionListener(new BeanCanFrame_jButton0_actionAdapter(this)); 100 | jButton11.setText("*"); 101 | jButton11.addActionListener(new BeanCanFrame_jButton11_actionAdapter(this)); 102 | jButton12.setAction(null); 103 | jButton12.setText("#"); 104 | jButton12.addActionListener(new BeanCanFrame_jButton12_actionAdapter(this)); 105 | jPanel2.setLayout(borderLayout3); 106 | status.setText("No Conectado"); 107 | jPanel4.setOpaque(true); 108 | jPanel4.setLayout(borderLayout6); 109 | act.setText("Llamar"); 110 | act.addActionListener(new BeanCanFrame_act_actionAdapter(this)); 111 | contentPane.setActionMap(null); 112 | clear.setText("Borrar"); 113 | clear.addActionListener(new BeanCanFrame_clear_actionAdapter(this)); 114 | jPanel5.setLayout(gridLayout2); 115 | gridLayout2.setColumns(2); 116 | jPanel7.setLayout(borderLayout4); 117 | jPanel6.setLayout(borderLayout5); 118 | jMenuFile.add(jMenuFileExit); 119 | jMenuHelp.add(jMenuHelpAbout); 120 | jMenuBar1.add(jMenuFile); 121 | jMenuBar1.add(jMenuHelp); 122 | contentPane.add(jPanel1, BorderLayout.CENTER); 123 | jPanel1.add(jPanel2, BorderLayout.NORTH); 124 | jPanel2.add(dialString, BorderLayout.CENTER); 125 | jPanel1.add(jPanel3, BorderLayout.CENTER); 126 | jPanel3.add(jButton1, null); 127 | jPanel3.add(jButton2, null); 128 | jPanel3.add(jButton3, null); 129 | jPanel3.add(jButton4, null); 130 | jPanel3.add(jButton5, null); 131 | jPanel3.add(jButton6, null); 132 | jPanel3.add(jButton7, null); 133 | jPanel3.add(jButton8, null); 134 | jPanel3.add(jButton9, null); 135 | jPanel3.add(jButton11, null); 136 | jPanel3.add(jButton0, null); 137 | jPanel3.add(jButton12, null); 138 | contentPane.add(jPanel4, BorderLayout.SOUTH); 139 | jPanel4.add(status, BorderLayout.CENTER); 140 | contentPane.add(jPanel5, BorderLayout.EAST); 141 | jPanel5.add(jPanel7, null); 142 | jPanel5.add(jPanel6, null); 143 | jPanel2.add(act, BorderLayout.EAST); 144 | jPanel2.add(clear, BorderLayout.WEST); 145 | this.setJMenuBar(jMenuBar1); 146 | 147 | } 148 | 149 | 150 | void hold() { 151 | 152 | } 153 | 154 | void button_action(ActionEvent e) { 155 | String t = e.getActionCommand(); 156 | String s = this.dialString.getText(); 157 | s = s + t; 158 | dialString.setText(s); 159 | } 160 | 161 | void dialString_actionPerformed(ActionEvent e) { 162 | String num = dialString.getText(); 163 | status.setText("Marcando: " + num); 164 | } 165 | 166 | void clear_actionPerformed(ActionEvent e) { 167 | dialString.setText(""); 168 | } 169 | 170 | void act_actionPerformed(ActionEvent e) { 171 | dialString_actionPerformed(e); 172 | } 173 | 174 | 175 | //Overridden so we can exit when window is closed 176 | @Override 177 | protected void processWindowEvent(WindowEvent e) { 178 | super.processWindowEvent(e); 179 | if (e.getID() == WindowEvent.WINDOW_CLOSING) { 180 | System.exit(0); 181 | } 182 | } 183 | 184 | /** 185 | * Acciones de Botones 186 | * 187 | * @author Sebastian 188 | */ 189 | 190 | class BeanCanFrame_jButton1_actionAdapter implements java.awt.event.ActionListener { 191 | BeanCanFrame adaptee; 192 | 193 | BeanCanFrame_jButton1_actionAdapter(BeanCanFrame adaptee) { 194 | this.adaptee = adaptee; 195 | } 196 | 197 | @Override 198 | public void actionPerformed(ActionEvent e) { 199 | DTMFGenerator.playTone("1"); 200 | 201 | adaptee.button_action(e); 202 | } 203 | } 204 | 205 | class BeanCanFrame_jButton2_actionAdapter implements java.awt.event.ActionListener { 206 | BeanCanFrame adaptee; 207 | 208 | BeanCanFrame_jButton2_actionAdapter(BeanCanFrame adaptee) { 209 | this.adaptee = adaptee; 210 | } 211 | 212 | @Override 213 | public void actionPerformed(ActionEvent e) { 214 | DTMFGenerator.playTone("2"); 215 | adaptee.button_action(e); 216 | } 217 | } 218 | 219 | class BeanCanFrame_jButton3_actionAdapter implements java.awt.event.ActionListener { 220 | BeanCanFrame adaptee; 221 | 222 | BeanCanFrame_jButton3_actionAdapter(BeanCanFrame adaptee) { 223 | this.adaptee = adaptee; 224 | } 225 | 226 | @Override 227 | public void actionPerformed(ActionEvent e) { 228 | DTMFGenerator.playTone("3"); 229 | adaptee.button_action(e); 230 | } 231 | } 232 | 233 | class BeanCanFrame_jButton4_actionAdapter implements java.awt.event.ActionListener { 234 | BeanCanFrame adaptee; 235 | 236 | BeanCanFrame_jButton4_actionAdapter(BeanCanFrame adaptee) { 237 | this.adaptee = adaptee; 238 | } 239 | 240 | @Override 241 | public void actionPerformed(ActionEvent e) { 242 | DTMFGenerator.playTone("4"); 243 | adaptee.button_action(e); 244 | } 245 | } 246 | 247 | class BeanCanFrame_jButton5_actionAdapter implements java.awt.event.ActionListener { 248 | BeanCanFrame adaptee; 249 | 250 | BeanCanFrame_jButton5_actionAdapter(BeanCanFrame adaptee) { 251 | this.adaptee = adaptee; 252 | } 253 | 254 | @Override 255 | public void actionPerformed(ActionEvent e) { 256 | DTMFGenerator.playTone("5"); 257 | adaptee.button_action(e); 258 | } 259 | } 260 | 261 | class BeanCanFrame_jButton6_actionAdapter implements java.awt.event.ActionListener { 262 | BeanCanFrame adaptee; 263 | 264 | BeanCanFrame_jButton6_actionAdapter(BeanCanFrame adaptee) { 265 | this.adaptee = adaptee; 266 | } 267 | 268 | @Override 269 | public void actionPerformed(ActionEvent e) { 270 | DTMFGenerator.playTone("6"); 271 | adaptee.button_action(e); 272 | } 273 | } 274 | 275 | class BeanCanFrame_jButton7_actionAdapter implements java.awt.event.ActionListener { 276 | BeanCanFrame adaptee; 277 | 278 | BeanCanFrame_jButton7_actionAdapter(BeanCanFrame adaptee) { 279 | this.adaptee = adaptee; 280 | } 281 | 282 | @Override 283 | public void actionPerformed(ActionEvent e) { 284 | DTMFGenerator.playTone("7"); 285 | adaptee.button_action(e); 286 | } 287 | } 288 | 289 | class BeanCanFrame_jButton8_actionAdapter implements java.awt.event.ActionListener { 290 | BeanCanFrame adaptee; 291 | 292 | BeanCanFrame_jButton8_actionAdapter(BeanCanFrame adaptee) { 293 | this.adaptee = adaptee; 294 | } 295 | 296 | @Override 297 | public void actionPerformed(ActionEvent e) { 298 | DTMFGenerator.playTone("8"); 299 | adaptee.button_action(e); 300 | } 301 | } 302 | 303 | class BeanCanFrame_jButton9_actionAdapter implements java.awt.event.ActionListener { 304 | BeanCanFrame adaptee; 305 | 306 | BeanCanFrame_jButton9_actionAdapter(BeanCanFrame adaptee) { 307 | this.adaptee = adaptee; 308 | } 309 | 310 | @Override 311 | public void actionPerformed(ActionEvent e) { 312 | DTMFGenerator.playTone("9"); 313 | adaptee.button_action(e); 314 | } 315 | } 316 | 317 | class BeanCanFrame_jButton11_actionAdapter implements java.awt.event.ActionListener { 318 | BeanCanFrame adaptee; 319 | 320 | BeanCanFrame_jButton11_actionAdapter(BeanCanFrame adaptee) { 321 | this.adaptee = adaptee; 322 | } 323 | 324 | @Override 325 | public void actionPerformed(ActionEvent e) { 326 | DTMFGenerator.playTone("*"); 327 | adaptee.button_action(e); 328 | 329 | } 330 | } 331 | 332 | class BeanCanFrame_jButton0_actionAdapter implements java.awt.event.ActionListener { 333 | BeanCanFrame adaptee; 334 | 335 | BeanCanFrame_jButton0_actionAdapter(BeanCanFrame adaptee) { 336 | this.adaptee = adaptee; 337 | } 338 | 339 | @Override 340 | public void actionPerformed(ActionEvent e) { 341 | DTMFGenerator.playTone("0"); 342 | adaptee.button_action(e); 343 | } 344 | } 345 | 346 | class BeanCanFrame_jButton12_actionAdapter implements java.awt.event.ActionListener { 347 | BeanCanFrame adaptee; 348 | 349 | BeanCanFrame_jButton12_actionAdapter(BeanCanFrame adaptee) { 350 | this.adaptee = adaptee; 351 | } 352 | 353 | @Override 354 | public void actionPerformed(ActionEvent e) { 355 | DTMFGenerator.playTone("#"); 356 | adaptee.button_action(e); 357 | } 358 | } 359 | 360 | 361 | class BeanCanFrame_dialString_actionAdapter implements java.awt.event.ActionListener { 362 | BeanCanFrame adaptee; 363 | 364 | BeanCanFrame_dialString_actionAdapter(BeanCanFrame adaptee) { 365 | this.adaptee = adaptee; 366 | } 367 | 368 | @Override 369 | public void actionPerformed(ActionEvent e) { 370 | adaptee.dialString_actionPerformed(e); 371 | } 372 | } 373 | 374 | class BeanCanFrame_clear_actionAdapter implements java.awt.event.ActionListener { 375 | BeanCanFrame adaptee; 376 | 377 | BeanCanFrame_clear_actionAdapter(BeanCanFrame adaptee) { 378 | this.adaptee = adaptee; 379 | } 380 | 381 | @Override 382 | public void actionPerformed(ActionEvent e) { 383 | adaptee.clear_actionPerformed(e); 384 | } 385 | } 386 | 387 | class BeanCanFrame_act_actionAdapter implements java.awt.event.ActionListener { 388 | BeanCanFrame adaptee; 389 | 390 | BeanCanFrame_act_actionAdapter(BeanCanFrame adaptee) { 391 | this.adaptee = adaptee; 392 | } 393 | 394 | @Override 395 | public void actionPerformed(ActionEvent e) { 396 | adaptee.act_actionPerformed(e); 397 | } 398 | } 399 | 400 | 401 | } -------------------------------------------------------------------------------- /src/main/java/org/asteriskjava/iax/ui/BeanCanFrameManager.java: -------------------------------------------------------------------------------- 1 | 2 | package org.asteriskjava.iax.ui; 3 | 4 | import org.asteriskjava.iax.audio.javasound.Audio8k; 5 | import org.asteriskjava.iax.audio.javasound.AudioInterface; 6 | import org.asteriskjava.iax.protocol.*; 7 | 8 | import java.awt.event.ActionEvent; 9 | import java.net.SocketException; 10 | 11 | 12 | public class BeanCanFrameManager extends BeanCanFrame implements ProtocolEventListener, CallManager { 13 | 14 | private Call _ca = null; 15 | private Friend _peer = null; 16 | private String _username = ""; 17 | private String _password = ""; 18 | private String _host = ""; 19 | private Binder _bind = null; 20 | private boolean _isApplet = false; 21 | private AudioInterface _audioBase = null; 22 | 23 | public BeanCanFrameManager(boolean isApplet, int level, String host) { 24 | super(); 25 | Log.setLevel(level); 26 | _isApplet = isApplet; 27 | _host = host; 28 | } 29 | 30 | public void start() { 31 | this.setVisible(true); 32 | _audioBase = new Audio8k(); 33 | try { 34 | _bind = new BinderSE(_host, _audioBase); 35 | } catch (SocketException ex) { 36 | status.setText(ex.getMessage()); 37 | } 38 | 39 | } 40 | 41 | public void stop() { 42 | if (_bind != null) { 43 | _bind.stop(); 44 | } 45 | this.hide(); 46 | status.setText("Stopped"); 47 | _bind = null; 48 | } 49 | 50 | public BeanCanFrameManager(String username, String password, String host, boolean isApplet, int level) { 51 | this(isApplet, level, host); 52 | _username = username; 53 | _password = password; 54 | } 55 | 56 | void register() { 57 | if (_bind == null) { 58 | start(); 59 | } 60 | try { 61 | 62 | _bind.register(_username, _password, this, true); 63 | } catch (Exception ex) { 64 | status.setText(ex.getMessage()); 65 | } 66 | } 67 | 68 | /** 69 | * newCall 70 | * 71 | * @param c Call 72 | */ 73 | @Override 74 | public void newCall(Call c) { 75 | Log.debug("Llamada Entrante "); 76 | if (_ca == null) { 77 | _ca = c; 78 | Log.debug("_ca == null :" + _ca.getStatus()); 79 | this.status.setText(c.getStatus()); 80 | if (_ca.getIsInbound()) { 81 | act.setText("Atender"); 82 | } else { 83 | act.setText("Cortar"); 84 | } 85 | } else { 86 | Log.debug("_ca != null :" + _ca.getStatus()); 87 | this.status.setText("Ignorando llamada Entrante"); 88 | } 89 | } 90 | 91 | /** 92 | * registered 93 | * 94 | * @param f Friend 95 | * @param s boolean 96 | */ 97 | @Override 98 | public void registered(Friend f, boolean s) { 99 | _peer = f; 100 | this.status.setText(_peer.getStatus()); 101 | } 102 | 103 | 104 | @Override 105 | public boolean accept(Call ca) { 106 | Log.debug("Aceptada Entrante "); 107 | boolean ret = true; 108 | if (_ca != null) { 109 | ret = false; 110 | } 111 | return ret; 112 | } 113 | 114 | 115 | /** 116 | * hungUp 117 | * 118 | * @param c Call 119 | */ 120 | @Override 121 | public void hungUp(Call c) { 122 | _ca = null; 123 | status.setText("Disponible"); 124 | act.setText("Llamar"); 125 | } 126 | 127 | /** 128 | * ringing 129 | * 130 | * @param c Call 131 | */ 132 | @Override 133 | public void ringing(Call c) { 134 | status.setText("Ringing"); 135 | } 136 | 137 | /** 138 | * Lets us know that the call we made is answered (or 139 | * not). 140 | * 141 | * @param c Call 142 | * @see ProtocolEventListener#answered(Call) 143 | */ 144 | @Override 145 | public void answered(Call c) { 146 | status.setText("Antendida " + c.isAnswered()); 147 | } 148 | 149 | /** 150 | * Called when it is known whether or not friend can reach its host 151 | * (PBX). 152 | * 153 | * @param f Friend 154 | * @param b Whether friend can reach its host 155 | * @param roundtrip The round trip (ms) of the request 156 | * @todo implement 157 | */ 158 | @Override 159 | public void setHostReachable(Friend f, boolean b, int roundtrip) { 160 | Log.warn("setHostReachable " + b + ", roundtrip " + roundtrip); 161 | } 162 | 163 | /** 164 | */ 165 | @Override 166 | void dialString_actionPerformed(ActionEvent e) { 167 | if (_ca == null) { 168 | if (_peer != null) { 169 | String num = dialString.getText(); 170 | _peer.newCall(_username, _password, num, null, null); 171 | } 172 | } else { 173 | if (_ca.getIsInbound()) { 174 | if (_ca.isAnswered()) { 175 | _ca.hangup(); 176 | } else { 177 | _ca.answer(); 178 | act.setText("Cortar"); 179 | } 180 | } else { 181 | _ca.hangup(); 182 | } 183 | } 184 | } 185 | 186 | 187 | @Override 188 | void button_action(ActionEvent e) { 189 | if (_ca == null) { 190 | super.button_action(e); 191 | } else { 192 | String t = e.getActionCommand(); 193 | _ca.sendDTMF(t.charAt(0)); 194 | status.setText("Enviado dtmf " + t); 195 | } 196 | } 197 | 198 | @Override 199 | void hold() { 200 | if (_ca != null) { 201 | _ca.hold(); 202 | } 203 | } 204 | 205 | @Override 206 | void clear_actionPerformed(ActionEvent e) { 207 | dialString.setText(""); 208 | } 209 | 210 | public String get_host() { 211 | return _host; 212 | } 213 | 214 | public String get_password() { 215 | return _password; 216 | } 217 | 218 | public String get_username() { 219 | return _username; 220 | } 221 | 222 | public void set_username(String _username) { 223 | this._username = _username; 224 | } 225 | 226 | public void set_password(String _password) { 227 | this._password = _password; 228 | } 229 | 230 | public void set_host(String _host) { 231 | this._host = _host; 232 | } 233 | 234 | /** 235 | * set_debug 236 | * 237 | * @param debug int 238 | */ 239 | public void set_debug(int debug) { 240 | Log.setLevel(debug); 241 | } 242 | 243 | } 244 | -------------------------------------------------------------------------------- /src/main/java/org/asteriskjava/iax/ui/GuiEventSender.java: -------------------------------------------------------------------------------- 1 | 2 | package org.asteriskjava.iax.ui; 3 | 4 | import org.asteriskjava.iax.protocol.Call; 5 | import org.asteriskjava.iax.protocol.Friend; 6 | import org.asteriskjava.iax.protocol.ProtocolEventListener; 7 | 8 | /** 9 | * Decouples events from the main threads. This class it used by Friend. 10 | */ 11 | 12 | public class GuiEventSender implements ProtocolEventListener { 13 | 14 | private ProtocolEventListener _gui; 15 | private Call _call; 16 | 17 | /** 18 | * Constructor for the GuiEventSender object 19 | * 20 | * @param gui The protocol event listener 21 | */ 22 | public GuiEventSender(ProtocolEventListener gui) { 23 | _gui = gui; 24 | } 25 | 26 | /** 27 | * Received a new call. 28 | * Via invokeLater() this is passed on to the ProtocolEventListener parameter. 29 | * 30 | * @param c The call object 31 | */ 32 | public void newCall(Call c) { 33 | _call = c; 34 | Runnable r = new Runnable() { 35 | public void run() { 36 | if (_gui != null) { 37 | _gui.newCall(_call); 38 | } 39 | } 40 | }; 41 | javax.swing.SwingUtilities.invokeLater(r); 42 | } 43 | 44 | /** 45 | * Hung up. 46 | * Via invokeLater() this is passed on to the ProtocolEventListener parameter. 47 | * 48 | * @param c The call object 49 | */ 50 | public void hungUp(Call c) { 51 | _call = c; 52 | Runnable r = new Runnable() { 53 | public void run() { 54 | if (_gui != null) { 55 | _gui.hungUp(_call); 56 | } 57 | } 58 | }; 59 | javax.swing.SwingUtilities.invokeLater(r); 60 | } 61 | 62 | /** 63 | * Ringing. 64 | * Via invokeLater() this is passed on to the ProtocolEventListener parameter. 65 | * 66 | * @param c The call object 67 | */ 68 | public void ringing(Call c) { 69 | _call = c; 70 | Runnable r = new Runnable() { 71 | public void run() { 72 | if (_gui != null) { 73 | _gui.ringing(_call); 74 | } 75 | } 76 | }; 77 | javax.swing.SwingUtilities.invokeLater(r); 78 | } 79 | 80 | /** 81 | * Answered. 82 | * Via invokeLater() this is passed on to the ProtocolEventListener parameter. 83 | * 84 | * @param c The call object 85 | */ 86 | public void answered(Call c) { 87 | _call = c; 88 | Runnable r = new Runnable() { 89 | public void run() { 90 | if (_gui != null) { 91 | _gui.answered(_call); 92 | } 93 | } 94 | }; 95 | javax.swing.SwingUtilities.invokeLater(r); 96 | } 97 | 98 | /** 99 | * registered 100 | * 101 | * @param f Friend 102 | * @param s boolean 103 | */ 104 | public void registered(Friend f, boolean s) { 105 | final Friend ff = f; 106 | final boolean fs = s; 107 | Runnable r = new Runnable() { 108 | public void run() { 109 | if (_gui != null) { 110 | _gui.registered(ff, fs); 111 | } 112 | } 113 | }; 114 | javax.swing.SwingUtilities.invokeLater(r); 115 | } 116 | 117 | /** 118 | * setHostReachable 119 | * 120 | * @param f Friend 121 | * @param b boolean 122 | * @param roundtrip int 123 | */ 124 | public void setHostReachable(Friend f, boolean b, int roundtrip) { 125 | final Friend ff = f; 126 | final boolean fb = b; 127 | final int fr = roundtrip; 128 | Runnable r = new Runnable() { 129 | public void run() { 130 | if (_gui != null) { 131 | _gui.setHostReachable(ff, fb, fr); 132 | } 133 | } 134 | }; 135 | javax.swing.SwingUtilities.invokeLater(r); 136 | 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /src/main/java/org/asteriskjava/iax/util/ByteBuffer.java: -------------------------------------------------------------------------------- 1 | package org.asteriskjava.iax.util; 2 | 3 | public class ByteBuffer { 4 | private byte[] myStore = null; // My backing store 5 | private int pos = 0; // Position index 6 | private int offset = 0; // into backing store to enable slicing 7 | 8 | /** 9 | * allocate 10 | * 11 | * @param i int 12 | * @return ByteBuffer 13 | */ 14 | public static ByteBuffer allocate(int i) { 15 | ByteBuffer bb = new ByteBuffer(); 16 | bb.myStore = new byte[i]; 17 | bb.pos = 0; 18 | bb.offset = 0; 19 | return bb; 20 | } 21 | 22 | /** 23 | * wrap 24 | * 25 | * @param bs byte[] 26 | * @return ByteBuffer 27 | */ 28 | public static ByteBuffer wrap(byte[] bs) { 29 | ByteBuffer bb = new ByteBuffer(); 30 | bb.myStore = bs; 31 | bb.pos = 0; 32 | bb.offset = 0; 33 | return bb; 34 | } 35 | 36 | /** 37 | * slice 38 | * 39 | * @return ByteBuffer 40 | */ 41 | public ByteBuffer slice() { 42 | ByteBuffer bb = new ByteBuffer(); 43 | bb.myStore = myStore; 44 | bb.pos = 0; 45 | bb.offset = pos; 46 | return bb; 47 | } 48 | 49 | /** 50 | * array 51 | * 52 | * @return byte[] 53 | */ 54 | public byte[] array() { 55 | if (offset != 0) { 56 | throw new java.lang.IllegalStateException(); 57 | } 58 | return myStore; 59 | } 60 | 61 | /** 62 | * position 63 | * 64 | * @return int 65 | */ 66 | public int position() { 67 | return pos; 68 | } 69 | 70 | /** 71 | * getShort 72 | * 73 | * @return short 74 | */ 75 | public short getShort() { 76 | if (offset + pos + 2 > myStore.length) { 77 | throw new IndexOutOfBoundsException(); 78 | } 79 | short s = (short) ((myStore[offset + pos] << 8) + 80 | (myStore[offset + pos + 1] & 0xFF)); 81 | pos += 2; 82 | return s; 83 | } 84 | 85 | public short getShort(int of) { 86 | if (offset + of + 2 > myStore.length) { 87 | throw new IndexOutOfBoundsException(); 88 | } 89 | short s = (short) ((myStore[offset + of] << 8) + 90 | (myStore[offset + of + 1] & 0xFF)); 91 | return s; 92 | } 93 | 94 | /** 95 | * getInt 96 | * 97 | * @return int 98 | */ 99 | public int getInt() { 100 | if (offset + pos + 4 > myStore.length) { 101 | throw new IndexOutOfBoundsException(); 102 | } 103 | int i = (myStore[offset + pos] << 24) 104 | + ((myStore[offset + pos + 1] & 0xFF) << 16) 105 | + ((myStore[offset + pos + 2] & 0xFF) << 8) 106 | + (myStore[offset + pos + 3] & 0xFF); 107 | pos += 4; 108 | return i; 109 | } 110 | 111 | /** 112 | * get 113 | * 114 | * @return byte 115 | */ 116 | public byte get() { 117 | if (offset + pos + 1 > myStore.length) { 118 | throw new IndexOutOfBoundsException(); 119 | } 120 | return myStore[offset + pos++]; 121 | } 122 | 123 | /** 124 | * putChar 125 | * 126 | * @param c char 127 | */ 128 | public void putChar(char c) { 129 | if (offset + pos + 2 > myStore.length) { 130 | throw new IndexOutOfBoundsException(); 131 | } 132 | myStore[offset + pos++] = (byte) (((short) c) >> 8); 133 | myStore[offset + pos++] = (byte) c; 134 | } 135 | 136 | /** 137 | * putChar 138 | * 139 | * @param i int 140 | * @param c char 141 | */ 142 | public void putChar(int i, char c) { 143 | if (offset + i + 2 > myStore.length) { 144 | throw new IndexOutOfBoundsException(); 145 | } 146 | myStore[offset + i] = (byte) (((short) c) >> 8); 147 | myStore[offset + i + 1] = (byte) c; 148 | } 149 | 150 | /** 151 | * putInt 152 | * 153 | * @param i int 154 | */ 155 | public void putInt(int i) { 156 | if (offset + pos + 4 > myStore.length) { 157 | throw new IndexOutOfBoundsException(); 158 | } 159 | myStore[offset + pos++] = (byte) (i >> 24); 160 | myStore[offset + pos++] = (byte) ((i >> 16) & 0xff); 161 | myStore[offset + pos++] = (byte) ((i >> 8) & 0xff); 162 | myStore[offset + pos++] = (byte) (i & 0xff); 163 | } 164 | 165 | /** 166 | * put 167 | * 168 | * @param b byte 169 | */ 170 | public void put(byte b) { 171 | if (offset + pos + 1 > myStore.length) { 172 | throw new IndexOutOfBoundsException(); 173 | } 174 | myStore[pos] = b; 175 | pos++; 176 | } 177 | 178 | /** 179 | * put 180 | * 181 | * @param payload byte[] 182 | */ 183 | public void put(byte[] payload) { 184 | if (offset + pos + payload.length > myStore.length) { 185 | throw new IndexOutOfBoundsException(); 186 | } 187 | System.arraycopy(payload, 0, myStore, offset + pos, payload.length); 188 | pos += payload.length; 189 | } 190 | 191 | /** 192 | * getChar 193 | * 194 | * @return char 195 | */ 196 | public char getChar() { 197 | if (offset + pos + 2 > myStore.length) { 198 | throw new IndexOutOfBoundsException(); 199 | } 200 | short s = (short) ((myStore[offset + pos] << 8) + 201 | (myStore[offset + pos + 1] & 0xFF)); 202 | pos += 2; 203 | return (char) s; 204 | } 205 | 206 | /** 207 | * getChar 208 | * 209 | * @param i int 210 | * @return char 211 | */ 212 | public char getChar(int i) { 213 | if (offset + i + 2 > myStore.length) { 214 | throw new IndexOutOfBoundsException(); 215 | } 216 | short s = (short) ((myStore[offset + i] << 8) + 217 | (myStore[offset + i + 1] & 0xFF)); 218 | return (char) s; 219 | } 220 | 221 | /** 222 | * get 223 | * 224 | * @param b byte[] 225 | */ 226 | public void get(byte[] b) { 227 | int l = remaining(); 228 | if (l > b.length) { 229 | l = b.length; 230 | } 231 | System.arraycopy(myStore, offset + pos, b, 0, l); 232 | pos += l; 233 | } 234 | 235 | /** 236 | * remaining 237 | * 238 | * @return int 239 | */ 240 | public int remaining() { 241 | return myStore.length - offset - pos; 242 | } 243 | 244 | /** 245 | * putShort 246 | * 247 | * @param s short 248 | */ 249 | public void putShort(short s) { 250 | if (offset + pos + 2 > myStore.length) { 251 | throw new IndexOutOfBoundsException(); 252 | } 253 | myStore[offset + pos++] = (byte) (s >> 8); 254 | myStore[offset + pos++] = (byte) (s & 0xff); 255 | } 256 | 257 | public void putShort(int of, short s) { 258 | if (offset + of + 2 > myStore.length) { 259 | throw new IndexOutOfBoundsException(); 260 | } 261 | myStore[offset + of++] = (byte) (s >> 8); 262 | myStore[offset + of++] = (byte) (s & 0xff); 263 | } 264 | 265 | public boolean hasRemaining() { 266 | return (offset + pos < myStore.length); 267 | } 268 | } 269 | -------------------------------------------------------------------------------- /src/main/java/org/asteriskjava/iax/util/DTMFGenerator.java: -------------------------------------------------------------------------------- 1 | package org.asteriskjava.iax.util; 2 | 3 | 4 | import javax.sound.sampled.*; 5 | 6 | 7 | public class DTMFGenerator { 8 | 9 | private int NUM_BANDS = 10; 10 | 11 | private float frequencyArray[] = {697.0F, 770.0F, 852.0F, 941.0F, 1209.0F, 1336.0F, 1477.0F, 1633.0F, 440.0F, 523.25F}; 12 | 13 | private float Q1[] = new float[NUM_BANDS]; 14 | private float Q2[] = new float[NUM_BANDS]; 15 | private float freqCoeffValueArray[] = new float[NUM_BANDS]; 16 | private static boolean ringing = true; 17 | 18 | public void init(float sps) { 19 | for (int i = 0; i < NUM_BANDS; ++i) { 20 | Q1[i] = (float) java.lang.Math.sin(0.0F); 21 | Q2[i] = (float) java.lang.Math.sin(2.0F * java.lang.Math.PI * frequencyArray[i] / sps); 22 | freqCoeffValueArray[i] = (float) (2 * java.lang.Math.cos(2.0F * java.lang.Math.PI * frequencyArray[i] / sps)); 23 | } 24 | } 25 | 26 | public float getLow(String chr) { 27 | int idx = 0; 28 | if ("1".equals(chr)) { 29 | idx = 0; 30 | } else if ("2".equals(chr)) { 31 | idx = 0; 32 | } else if ("3".equals(chr)) { 33 | idx = 0; 34 | } else if ("4".equals(chr)) { 35 | idx = 1; 36 | } else if ("5".equals(chr)) { 37 | idx = 1; 38 | } else if ("6".equals(chr)) { 39 | idx = 1; 40 | } else if ("7".equals(chr)) { 41 | idx = 2; 42 | } else if ("8".equals(chr)) { 43 | idx = 2; 44 | } else if ("9".equals(chr)) { 45 | idx = 2; 46 | } else if ("*".equals(chr)) { 47 | idx = 3; 48 | } else if ("0".equals(chr)) { 49 | idx = 3; 50 | } else if ("#".equals(chr)) { 51 | idx = 3; 52 | } else if ("Ring".equals(chr)) { 53 | idx = 8; 54 | } 55 | float g; 56 | g = Q1[idx]; 57 | Q1[idx] = Q2[idx]; 58 | Q2[idx] = freqCoeffValueArray[idx] * Q1[idx] - g; 59 | return g; 60 | } 61 | 62 | public float getHigh(String chr) { 63 | int idx = 0; 64 | if ("1".equals(chr)) { 65 | idx = 4; 66 | } else if ("2".equals(chr)) { 67 | idx = 5; 68 | } else if ("3".equals(chr)) { 69 | idx = 6; 70 | } else if ("4".equals(chr)) { 71 | idx = 4; 72 | } else if ("5".equals(chr)) { 73 | idx = 5; 74 | } else if ("6".equals(chr)) { 75 | idx = 6; 76 | } else if ("7".equals(chr)) { 77 | idx = 4; 78 | } else if ("8".equals(chr)) { 79 | idx = 5; 80 | } else if ("9".equals(chr)) { 81 | idx = 6; 82 | } else if ("*".equals(chr)) { 83 | idx = 4; 84 | } else if ("0".equals(chr)) { 85 | idx = 5; 86 | } else if ("#".equals(chr)) { 87 | idx = 6; 88 | } else if ("Ring".equals(chr)) { 89 | idx = 9; 90 | } 91 | float g; 92 | g = Q1[idx]; 93 | Q1[idx] = Q2[idx]; 94 | Q2[idx] = freqCoeffValueArray[idx] * Q1[idx] - g; 95 | return g; 96 | } 97 | 98 | public float getDTMF(String chr) { 99 | return getLow(chr) + getHigh(chr); 100 | } 101 | 102 | public static void StopRing() { 103 | ringing = false; 104 | } 105 | 106 | 107 | public static void playRing() { 108 | ringing = true; 109 | Thread ring = new Thread() { 110 | 111 | @Override 112 | public void run() { 113 | while (ringing) { 114 | try { 115 | DTMFGenerator generator = new DTMFGenerator(); 116 | generator.init(8000.0F); 117 | AudioFormat pcmFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 8000.0F, 8, 1, 1, 8000.0F, false); 118 | DataLine.Info info = new DataLine.Info(SourceDataLine.class, pcmFormat); 119 | SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info); 120 | line.open(pcmFormat); 121 | line.start(); 122 | byte[] abData = new byte[160]; 123 | for (int i = 0; i < 150; ++i) { 124 | int available = line.available(); 125 | if (available < 1600) { 126 | Thread.sleep(150); 127 | } else { 128 | if (i < 50) { 129 | for (int j = 0; j < 160; ++j) { 130 | if ((i % 2) == 0) { 131 | abData[j] = (byte) ((generator.getLow("Ring") * 128.0F) * 0.1); 132 | } else { 133 | abData[j] = (byte) ((generator.getHigh("Ring") * 128.0F) * 0.1); 134 | } 135 | } 136 | } else { 137 | for (int j = 0; j < 160; ++j) { 138 | abData[j] = (byte) 0; 139 | } 140 | } 141 | line.write(abData, 0, abData.length); 142 | } 143 | } 144 | line.drain(); 145 | line.close(); 146 | } catch (LineUnavailableException e) { 147 | e.printStackTrace(); 148 | } catch (InterruptedException e) { 149 | e.printStackTrace(); 150 | } 151 | } 152 | } 153 | }; 154 | ring.start(); 155 | } 156 | 157 | 158 | public static void playTone(final String tone) { 159 | Thread toneThread = new Thread() { 160 | @Override 161 | public void run() { 162 | try { 163 | DTMFGenerator generator = new DTMFGenerator(); 164 | generator.init(8000.0F); 165 | AudioFormat pcmFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 8000.0F, 8, 1, 1, 8000.0F, false); 166 | DataLine.Info info = new DataLine.Info(SourceDataLine.class, pcmFormat); 167 | SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info); 168 | line.open(pcmFormat); 169 | line.start(); 170 | byte[] abData = new byte[160]; 171 | for (int i = 0; i < 10; ++i) { 172 | int available = line.available(); 173 | if (available < 1600) { 174 | Thread.sleep(150); 175 | } else { 176 | for (int j = 0; j < 160; ++j) { 177 | abData[j] = (byte) ((generator.getDTMF(tone) * 128.0F) * 0.1); 178 | } 179 | line.write(abData, 0, abData.length); 180 | } 181 | } 182 | line.drain(); 183 | line.close(); 184 | } catch (LineUnavailableException e) { 185 | e.printStackTrace(); 186 | } catch (InterruptedException e) { 187 | e.printStackTrace(); 188 | } 189 | } 190 | }; 191 | toneThread.start(); 192 | } 193 | 194 | } 195 | -------------------------------------------------------------------------------- /src/main/java/org/asteriskjava/iax/util/GeneralDigest.java: -------------------------------------------------------------------------------- 1 | package org.asteriskjava.iax.util; 2 | 3 | 4 | /** 5 | * base implementation of MD4 family style digest as outlined in 6 | * "Handbook of Applied Cryptography", pages 344 - 347. 7 | */ 8 | public abstract class GeneralDigest { 9 | private byte[] xBuf = new byte[4]; 10 | private int xBufOff = 0; 11 | 12 | private long byteCount; 13 | 14 | /** 15 | * Standard constructor 16 | */ 17 | protected GeneralDigest() { 18 | } 19 | 20 | /** 21 | * Copy constructor. We are using copy constructors in place 22 | * of the Object.clone() interface as this interface is not 23 | * supported by J2ME. 24 | */ 25 | protected GeneralDigest(GeneralDigest t) { 26 | System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length); 27 | xBufOff = t.xBufOff; 28 | byteCount = t.byteCount; 29 | } 30 | 31 | public void update( 32 | byte in) { 33 | xBuf[xBufOff++] = in; 34 | 35 | if (xBufOff == xBuf.length) { 36 | processWord(xBuf, 0); 37 | xBufOff = 0; 38 | } 39 | 40 | byteCount++; 41 | } 42 | 43 | public void update( 44 | byte[] in, 45 | int inOff, 46 | int len) { 47 | // 48 | // fill the current word 49 | // 50 | while ((xBufOff != 0) && (len > 0)) { 51 | update(in[inOff]); 52 | 53 | inOff++; 54 | len--; 55 | } 56 | 57 | // 58 | // process whole words. 59 | // 60 | while (len > 4) { 61 | processWord(in, inOff); 62 | 63 | inOff += 4; 64 | len -= 4; 65 | byteCount += 4; 66 | } 67 | 68 | // 69 | // load in the remainder. 70 | // 71 | while (len > 0) { 72 | update(in[inOff]); 73 | 74 | inOff++; 75 | len--; 76 | } 77 | } 78 | 79 | public void finish() { 80 | long bitLength = (byteCount << 3); 81 | 82 | // 83 | // add the pad bytes. 84 | // 85 | update((byte) 128); 86 | 87 | while (xBufOff != 0) { 88 | update((byte) 0); 89 | } 90 | 91 | processLength(bitLength); 92 | 93 | processBlock(); 94 | } 95 | 96 | public void reset() { 97 | byteCount = 0; 98 | 99 | xBufOff = 0; 100 | xBuf[0] = xBuf[1] = xBuf[2] = xBuf[3] = 0; 101 | } 102 | 103 | protected abstract void processWord(byte[] in, int inOff); 104 | 105 | protected abstract void processLength(long bitLength); 106 | 107 | protected abstract void processBlock(); 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/org/asteriskjava/iax/util/MD5Digest.java: -------------------------------------------------------------------------------- 1 | package org.asteriskjava.iax.util; 2 | 3 | 4 | /** 5 | * implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347. 6 | */ 7 | public class MD5Digest 8 | extends GeneralDigest { 9 | private static final int DIGEST_LENGTH = 16; 10 | 11 | private int H1, H2, H3, H4; // IV's 12 | 13 | private int[] X = new int[16]; 14 | private int xOff; 15 | 16 | /** 17 | * Standard constructor 18 | */ 19 | public MD5Digest() { 20 | reset(); 21 | } 22 | 23 | /** 24 | * Copy constructor. This will copy the state of the provided 25 | * message digest. 26 | */ 27 | public MD5Digest(MD5Digest t) { 28 | super(t); 29 | 30 | H1 = t.H1; 31 | H2 = t.H2; 32 | H3 = t.H3; 33 | H4 = t.H4; 34 | 35 | System.arraycopy(t.X, 0, X, 0, t.X.length); 36 | xOff = t.xOff; 37 | } 38 | 39 | public String getAlgorithmName() { 40 | return "MD5"; 41 | } 42 | 43 | public int getDigestSize() { 44 | return DIGEST_LENGTH; 45 | } 46 | 47 | @Override 48 | protected void processWord( 49 | byte[] in, 50 | int inOff) { 51 | X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8) 52 | | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24); 53 | 54 | if (xOff == 16) { 55 | processBlock(); 56 | } 57 | } 58 | 59 | @Override 60 | protected void processLength( 61 | long bitLength) { 62 | if (xOff > 14) { 63 | processBlock(); 64 | } 65 | 66 | X[14] = (int) (bitLength & 0xffffffff); 67 | X[15] = (int) (bitLength >>> 32); 68 | } 69 | 70 | private void unpackWord( 71 | int word, 72 | byte[] out, 73 | int outOff) { 74 | out[outOff] = (byte) word; 75 | out[outOff + 1] = (byte) (word >>> 8); 76 | out[outOff + 2] = (byte) (word >>> 16); 77 | out[outOff + 3] = (byte) (word >>> 24); 78 | } 79 | 80 | public int doFinal( 81 | byte[] out, 82 | int outOff) { 83 | finish(); 84 | 85 | unpackWord(H1, out, outOff); 86 | unpackWord(H2, out, outOff + 4); 87 | unpackWord(H3, out, outOff + 8); 88 | unpackWord(H4, out, outOff + 12); 89 | 90 | reset(); 91 | 92 | return DIGEST_LENGTH; 93 | } 94 | 95 | /** 96 | * reset the chaining variables to the IV values. 97 | */ 98 | @Override 99 | public void reset() { 100 | super.reset(); 101 | 102 | H1 = 0x67452301; 103 | H2 = 0xefcdab89; 104 | H3 = 0x98badcfe; 105 | H4 = 0x10325476; 106 | 107 | xOff = 0; 108 | 109 | for (int i = 0; i != X.length; i++) { 110 | X[i] = 0; 111 | } 112 | } 113 | 114 | // 115 | // round 1 left rotates 116 | // 117 | private static final int S11 = 7; 118 | private static final int S12 = 12; 119 | private static final int S13 = 17; 120 | private static final int S14 = 22; 121 | 122 | // 123 | // round 2 left rotates 124 | // 125 | private static final int S21 = 5; 126 | private static final int S22 = 9; 127 | private static final int S23 = 14; 128 | private static final int S24 = 20; 129 | 130 | // 131 | // round 3 left rotates 132 | // 133 | private static final int S31 = 4; 134 | private static final int S32 = 11; 135 | private static final int S33 = 16; 136 | private static final int S34 = 23; 137 | 138 | // 139 | // round 4 left rotates 140 | // 141 | private static final int S41 = 6; 142 | private static final int S42 = 10; 143 | private static final int S43 = 15; 144 | private static final int S44 = 21; 145 | 146 | /* 147 | * rotate int x left n bits. 148 | */ 149 | private int rotateLeft( 150 | int x, 151 | int n) { 152 | return (x << n) | (x >>> (32 - n)); 153 | } 154 | 155 | /* 156 | * F, G, H and I are the basic MD5 functions. 157 | */ 158 | private int F( 159 | int u, 160 | int v, 161 | int w) { 162 | return (u & v) | (~u & w); 163 | } 164 | 165 | private int G( 166 | int u, 167 | int v, 168 | int w) { 169 | return (u & w) | (v & ~w); 170 | } 171 | 172 | private int H( 173 | int u, 174 | int v, 175 | int w) { 176 | return u ^ v ^ w; 177 | } 178 | 179 | private int K( 180 | int u, 181 | int v, 182 | int w) { 183 | return v ^ (u | ~w); 184 | } 185 | 186 | @Override 187 | protected void processBlock() { 188 | int a = H1; 189 | int b = H2; 190 | int c = H3; 191 | int d = H4; 192 | 193 | // 194 | // Round 1 - F cycle, 16 times. 195 | // 196 | a = rotateLeft((a + F(b, c, d) + X[0] + 0xd76aa478), S11) + b; 197 | d = rotateLeft((d + F(a, b, c) + X[1] + 0xe8c7b756), S12) + a; 198 | c = rotateLeft((c + F(d, a, b) + X[2] + 0x242070db), S13) + d; 199 | b = rotateLeft((b + F(c, d, a) + X[3] + 0xc1bdceee), S14) + c; 200 | a = rotateLeft((a + F(b, c, d) + X[4] + 0xf57c0faf), S11) + b; 201 | d = rotateLeft((d + F(a, b, c) + X[5] + 0x4787c62a), S12) + a; 202 | c = rotateLeft((c + F(d, a, b) + X[6] + 0xa8304613), S13) + d; 203 | b = rotateLeft((b + F(c, d, a) + X[7] + 0xfd469501), S14) + c; 204 | a = rotateLeft((a + F(b, c, d) + X[8] + 0x698098d8), S11) + b; 205 | d = rotateLeft((d + F(a, b, c) + X[9] + 0x8b44f7af), S12) + a; 206 | c = rotateLeft((c + F(d, a, b) + X[10] + 0xffff5bb1), S13) + d; 207 | b = rotateLeft((b + F(c, d, a) + X[11] + 0x895cd7be), S14) + c; 208 | a = rotateLeft((a + F(b, c, d) + X[12] + 0x6b901122), S11) + b; 209 | d = rotateLeft((d + F(a, b, c) + X[13] + 0xfd987193), S12) + a; 210 | c = rotateLeft((c + F(d, a, b) + X[14] + 0xa679438e), S13) + d; 211 | b = rotateLeft((b + F(c, d, a) + X[15] + 0x49b40821), S14) + c; 212 | 213 | // 214 | // Round 2 - G cycle, 16 times. 215 | // 216 | a = rotateLeft((a + G(b, c, d) + X[1] + 0xf61e2562), S21) + b; 217 | d = rotateLeft((d + G(a, b, c) + X[6] + 0xc040b340), S22) + a; 218 | c = rotateLeft((c + G(d, a, b) + X[11] + 0x265e5a51), S23) + d; 219 | b = rotateLeft((b + G(c, d, a) + X[0] + 0xe9b6c7aa), S24) + c; 220 | a = rotateLeft((a + G(b, c, d) + X[5] + 0xd62f105d), S21) + b; 221 | d = rotateLeft((d + G(a, b, c) + X[10] + 0x02441453), S22) + a; 222 | c = rotateLeft((c + G(d, a, b) + X[15] + 0xd8a1e681), S23) + d; 223 | b = rotateLeft((b + G(c, d, a) + X[4] + 0xe7d3fbc8), S24) + c; 224 | a = rotateLeft((a + G(b, c, d) + X[9] + 0x21e1cde6), S21) + b; 225 | d = rotateLeft((d + G(a, b, c) + X[14] + 0xc33707d6), S22) + a; 226 | c = rotateLeft((c + G(d, a, b) + X[3] + 0xf4d50d87), S23) + d; 227 | b = rotateLeft((b + G(c, d, a) + X[8] + 0x455a14ed), S24) + c; 228 | a = rotateLeft((a + G(b, c, d) + X[13] + 0xa9e3e905), S21) + b; 229 | d = rotateLeft((d + G(a, b, c) + X[2] + 0xfcefa3f8), S22) + a; 230 | c = rotateLeft((c + G(d, a, b) + X[7] + 0x676f02d9), S23) + d; 231 | b = rotateLeft((b + G(c, d, a) + X[12] + 0x8d2a4c8a), S24) + c; 232 | 233 | // 234 | // Round 3 - H cycle, 16 times. 235 | // 236 | a = rotateLeft((a + H(b, c, d) + X[5] + 0xfffa3942), S31) + b; 237 | d = rotateLeft((d + H(a, b, c) + X[8] + 0x8771f681), S32) + a; 238 | c = rotateLeft((c + H(d, a, b) + X[11] + 0x6d9d6122), S33) + d; 239 | b = rotateLeft((b + H(c, d, a) + X[14] + 0xfde5380c), S34) + c; 240 | a = rotateLeft((a + H(b, c, d) + X[1] + 0xa4beea44), S31) + b; 241 | d = rotateLeft((d + H(a, b, c) + X[4] + 0x4bdecfa9), S32) + a; 242 | c = rotateLeft((c + H(d, a, b) + X[7] + 0xf6bb4b60), S33) + d; 243 | b = rotateLeft((b + H(c, d, a) + X[10] + 0xbebfbc70), S34) + c; 244 | a = rotateLeft((a + H(b, c, d) + X[13] + 0x289b7ec6), S31) + b; 245 | d = rotateLeft((d + H(a, b, c) + X[0] + 0xeaa127fa), S32) + a; 246 | c = rotateLeft((c + H(d, a, b) + X[3] + 0xd4ef3085), S33) + d; 247 | b = rotateLeft((b + H(c, d, a) + X[6] + 0x04881d05), S34) + c; 248 | a = rotateLeft((a + H(b, c, d) + X[9] + 0xd9d4d039), S31) + b; 249 | d = rotateLeft((d + H(a, b, c) + X[12] + 0xe6db99e5), S32) + a; 250 | c = rotateLeft((c + H(d, a, b) + X[15] + 0x1fa27cf8), S33) + d; 251 | b = rotateLeft((b + H(c, d, a) + X[2] + 0xc4ac5665), S34) + c; 252 | 253 | // 254 | // Round 4 - K cycle, 16 times. 255 | // 256 | a = rotateLeft((a + K(b, c, d) + X[0] + 0xf4292244), S41) + b; 257 | d = rotateLeft((d + K(a, b, c) + X[7] + 0x432aff97), S42) + a; 258 | c = rotateLeft((c + K(d, a, b) + X[14] + 0xab9423a7), S43) + d; 259 | b = rotateLeft((b + K(c, d, a) + X[5] + 0xfc93a039), S44) + c; 260 | a = rotateLeft((a + K(b, c, d) + X[12] + 0x655b59c3), S41) + b; 261 | d = rotateLeft((d + K(a, b, c) + X[3] + 0x8f0ccc92), S42) + a; 262 | c = rotateLeft((c + K(d, a, b) + X[10] + 0xffeff47d), S43) + d; 263 | b = rotateLeft((b + K(c, d, a) + X[1] + 0x85845dd1), S44) + c; 264 | a = rotateLeft((a + K(b, c, d) + X[8] + 0x6fa87e4f), S41) + b; 265 | d = rotateLeft((d + K(a, b, c) + X[15] + 0xfe2ce6e0), S42) + a; 266 | c = rotateLeft((c + K(d, a, b) + X[6] + 0xa3014314), S43) + d; 267 | b = rotateLeft((b + K(c, d, a) + X[13] + 0x4e0811a1), S44) + c; 268 | a = rotateLeft((a + K(b, c, d) + X[4] + 0xf7537e82), S41) + b; 269 | d = rotateLeft((d + K(a, b, c) + X[11] + 0xbd3af235), S42) + a; 270 | c = rotateLeft((c + K(d, a, b) + X[2] + 0x2ad7d2bb), S43) + d; 271 | b = rotateLeft((b + K(c, d, a) + X[9] + 0xeb86d391), S44) + c; 272 | 273 | H1 += a; 274 | H2 += b; 275 | H3 += c; 276 | H4 += d; 277 | 278 | // 279 | // reset the offset and clean out the word buffer. 280 | // 281 | xOff = 0; 282 | for (int i = 0; i != X.length; i++) { 283 | X[i] = 0; 284 | } 285 | } 286 | } 287 | -------------------------------------------------------------------------------- /src/site/apt/building.apt: -------------------------------------------------------------------------------- 1 | --- 2 | Building with Maven 3 | --- 4 | Stefan Reuter 5 | --- 6 | $Id$ 7 | 8 | Building with Maven 9 | 10 | Retrieve the latest version of Asterisk-Java IAX from SVN: 11 | 12 | --- 13 | svn co http://svn.reucon.net/repos/asterisk-java-iax/trunk asterisk-java-iax 14 | --- 15 | 16 | Then change to the created asterisk-java-iax directory and use Maven2 to 17 | build the project 18 | 19 | --- 20 | cd asterisk-java-iax 21 | mvn install 22 | --- 23 | 24 | This will create the asterisk-java-iax-${VERSION}.jar in the target subdirectory 25 | as well as in your local maven repository. -------------------------------------------------------------------------------- /src/site/apt/faq.apt: -------------------------------------------------------------------------------- 1 | --- 2 | Frequently Asked Questions 3 | --- 4 | Martin Smith 5 | --- 6 | $Id$ 7 | 8 | Frequently Asked Questions 9 | 10 | * Where is the mailing list? 11 | 12 | From {{{http://blogs.reucon.com/asterisk-java/2008/01/17/faq_where_is_the_mailing_list.html}this blog post}}: 13 | 14 | It seems we've hidden the link to our mailing lists a bit too well. 15 | 16 | We have two mailing lists: 17 | 18 | * Asterisk-Java Users for users of Asterisk-Java seeking help 19 | 20 | * Asterisk-Java Devel for developers of Asterisk-Java, i.e. the guys enhancing the library code itself. This list not intended to provide support regarding the use of Asterisk-Java. 21 | 22 | You can find the subscription details for both lists {{{http://asterisk-java.org/development/mail-lists.html}here}}. 23 | 24 | You might also be interested in our {{{http://jira.reucon.org}Bug Tracker}} where you can look for known issues, post new bug reports and submit patches. 25 | 26 | * Will Asterisk-Java IAX be included in the Asterisk-Java jar file or will it remain separate? 27 | 28 | Asterisk-Java IAX will remain a separate project for two reasons: 29 | 30 | * One of the main use cases for Asterisk-Java IAX is as an applet, so a small footprint matters 31 | 32 | * Asterisk-Java IAX is released under GPLv3 while Asterisk-Java is released unter Apache License, therefore 33 | the two projects can't be merged. 34 | 35 | -------------------------------------------------------------------------------- /src/site/apt/index.apt: -------------------------------------------------------------------------------- 1 | --- 2 | Asterisk-Java IAX 3 | --- 4 | Stefan Reuter 5 | --- 6 | $Id$ 7 | 8 | Asterisk-Java IAX 9 | 10 | Asterisk-Java IAX is a Java implementation of the IAX2 protocol as defined in 11 | {{{http://www.rfc-editor.org/authors/rfc5456.txt}RFC 5456}}. 12 | 13 | It is based on code developed by Tim Panton of {{{http://www.westhawk.co.uk}Westhawk Ltd}} for 14 | {{{http://www.mexuar.com/}Mexuar Communications}} released under GPLv3 in 2008. 15 | 16 | For now we have included a {{{demo.html}small demo page}} by Wolfgang that shows how to make use 17 | of the applet and access it from JavaScript. 18 | 19 | * License 20 | 21 | Asterisk-Java IAX is provided under the terms of the 22 | {{{http://www.gnu.org/licenses/gpl.txt}GNU General Public License, Version 3}}. 23 | 24 | The original code is Copyright 2005-2007 Mexuar Technologies Ltd. All Rights Reserved. 25 | 26 | * Status 27 | 28 | We plan to release Asterisk-Java IAX 1.0.0 as soon as possible. 29 | 30 | Ideas for the future include support for additional codecs like Speex and GSM. 31 | 32 | * Download 33 | 34 | Official releases and release candidates are available from the our 35 | {{{http://maven.reucon.com/public/org/asteriskjava/asterisk-javai-iax/}distribution site}}. 36 | 37 | The 38 | {{{http://maven.reucon.com/public-snapshot/org/asteriskjava/asterisk-java-iax/}snapshot distribution site}} 39 | hosts the latest snapshot releases. 40 | 41 | Please feel free to provide any feedback or ask for support via the 42 | {{{mail-lists.html}Asterisk-Java users mailing list}}. 43 | 44 | The latest development version of Asterisk-Java IAX is always available via SVN: 45 | 46 | +-----------------------------------------------------------------------------+ 47 | svn co http://svn.reucon.net/repos/asterisk-java-iax/trunk asterisk-java-iax 48 | +-----------------------------------------------------------------------------+ 49 | 50 | * Requirements 51 | 52 | At runtime Asterisk-Java requires a Java Runtime 53 | Environment (JRE) of at least version 1.5 (J2SE 5.0). 54 | 55 | * Related Projects 56 | 57 | {{{https://jain-sip.dev.java.net/}JAIN SIP}} contains RI, TCK, examples, tools for JAIN-SIP-1.2 58 | (JSR-32 maintenance release) and an SDP library that conforms to the public release of JSR 141 (JAIN-SDP) 59 | interfaces. JAIN-SIP RI is a full implementation of RFC 3261. 60 | 61 | {{{http://sip-communicator.org/}SIP Communicator}} is an audio/video Internet phone and instant messenger 62 | that supports some of the most popular instant messaging and telephony protocols such as SIP, Jabber, 63 | AIM/ICQ, MSN, Yahoo! Messenger, Bonjour, IRC, RSS and soon others like IAX.\ 64 | Available under the GNU Lesser General Public License (LGPL). 65 | 66 | * Sponsors 67 | 68 | Thanks to our sponsors: 69 | 70 | * JetBrains for providing a free license of 71 | {{{http://www.jetbrains.com/idea/}IntelliJ Idea}}. 72 | 73 | * {{{http://www.atlassian.com/}Atlassian}} for providing a free license of 74 | the excellent {{{http://www.atlassian.com/software/jira/}JIRA}} Bug tracker 75 | as well as {{{http://www.cenqua.com/clover/}Clover}} and 76 | {{{http://www.cenqua.com/fisheye/}FishEye}}. 77 | 78 | * YourKit {{{http://www.yourkit.com/}Java Profiler}}. 79 | 80 | * Contact 81 | 82 | You can reach me at <<
You will need your own IAX Account to test the applet - i do not provide one for you...
160 | 161 | 173 | 174 |