package iax.protocol.frame; import iax.protocol.util.ByteBuffer; import java.util.Enumeration; import java.util.Hashtable; /** * Protocol Control Frame. */ public class ProtocolControlFrame extends FullFrame { /** * IAX Protocol Control Frame, subclass value: NEW */ public static final int NEW_SC = 1; /** * IAX Protocol Control Frame, subclass value: PING */ public static final int PING_SC = 2; /** * IAX Protocol Control Frame, subclass value: PONG */ public static final int PONG_SC = 3; /** * IAX Protocol Control Frame, subclass value: ACK */ public static final int ACK_SC = 4; /** * IAX Protocol Control Frame, subclass value: HANGUP */ public static final int HANGUP_SC = 5; /** * IAX Protocol Control Frame, subclass value: REJECT */ public static final int REJECT_SC = 6; /** * IAX Protocol Control Frame, subclass value: ACCEPT */ public static final int ACCEPT_SC = 7; /** * IAX Protocol Control Frame, subclass value: AUTHREQ */ public static final int AUTHREQ_SC = 8; /** * IAX Protocol Control Frame, subclass value: AUTHREP */ public static final int AUTHREP_SC = 9; /** * IAX Protocol Control Frame, subclass value: INVAL */ public static final int INVAL_SC = 10; /** * IAX Protocol Control Frame, subclass value: LAGRQ */ public static final int LAGRQ_SC = 11; /** * IAX Protocol Control Frame, subclass value: LAGRP */ public static final int LAGRP_SC = 12; /** * IAX Protocol Control Frame, subclass value: REGREQ */ public static final int REGREQ_SC = 13; /** * IAX Protocol Control Frame, subclass value: REGAUTH */ public static final int REGAUTH_SC = 14; /** * IAX Protocol Control Frame, subclass value: REGACK */ public static final int REGACK_SC = 15; /** * IAX Protocol Control Frame, subclass value: REGREJ */ public static final int REGREJ_SC = 16; /** * IAX Protocol Control Frame, subclass value: REGREL */ public static final int REGREL_SC = 17; /** * IAX Protocol Control Frame, subclass value: VNAK */ public static final int VNAK_SC = 18; /** * IAX Protocol Control Frame, subclass value: DIAL */ public static final int DIAL_SC = 21; /** * IAX Protocol Control Frame, subclass value: QUELCH */ public static final int QUELCH_SC = 28; /** * IAX Protocol Control Frame, subclass value: UNQUELCH */ public static final int UNQUELCH_SC = 29; /** * IAX Protocol Control Frame, subclass value: POKE */ public static final int POKE_SC = 30; /** * IAX Protocol Control Frame, subclass value: UNSUPPORT */ public static final int UNSUPPORT_SC = 33; /** * IAX Protocol Control Frame, subclass value: TRANSFER */ public static final int TRANSFER_SC = 34; //Hasthable that containt frame information elements. private Hashtable infoElements; /** * Constructor. Initializes the frame. */ protected ProtocolControlFrame() { super(); } /** * Constructor. Initializes the frame with given values. * @param srcCallNo Source call number * @param retry Indicates if the frame is being retransmitted. * @param destCallNo Destination call number. * @param timeStamp Timestamp of the frame. * @param oSeqno Output sequence number. * @param iSeqno In put sequence number. * @param subclassValueFormat Indicates if subclass value is a 2 power or not. * @param subclass Frame subclass. */ public ProtocolControlFrame (int srcCallNo, boolean retry, int destCallNo, long timeStamp, int oSeqno, int iSeqno, boolean subclassValueFormat, int subclass) { super(Frame.PROTOCOLCONTROLFRAME_T, srcCallNo, retry, destCallNo, timeStamp, oSeqno, iSeqno, PROTOCOLCONTROL_FT, subclassValueFormat, subclass); this.infoElements = new Hashtable(); } /** * Constructor. Initializes the frame with given values. * @param buffer The buffer that contains the frame bytes. * @throws FrameException */ public ProtocolControlFrame(byte[] buffer) throws FrameException { super(Frame.PROTOCOLCONTROLFRAME_T, buffer); this.infoElements = new Hashtable(); try { byte[] iesBuffer = new byte[buffer.length - FULLFRAME_HEADER_LENGTH]; System.arraycopy(buffer, FULLFRAME_HEADER_LENGTH, iesBuffer, 0, iesBuffer.length); int bytesRemaining = iesBuffer.length; //This while iterate the buffer to search information elements. //These are variable in number, type and size. while(bytesRemaining > 0) { byte[] aux = new byte[bytesRemaining]; System.arraycopy(iesBuffer, iesBuffer.length - bytesRemaining, aux, 0, aux.length); ByteBuffer byteBuffer = new ByteBuffer(aux); int id = byteBuffer.get8bits(); int dataLength = byteBuffer.get8bits(); byte[] data = new byte[dataLength]; System.arraycopy(byteBuffer.getByteArray(), 0, data, 0, data.length); infoElements.put(id,data); bytesRemaining -= InfoElement.HEADER_LENGTH + dataLength; } int i=1; i++; } catch (Exception e) { throw new FrameException(e); } } /** * Gets the authentication method. * See IAX draft. * @return The value identifier of authentication method information element. * @throws FrameException */ public int getAuthMethods() throws FrameException { try { byte data[] = (byte[])infoElements.get(InfoElement.AUTHMETHODS); ByteBuffer byteBuffer = new ByteBuffer(data); return byteBuffer.get16bits(); } catch (Exception e) { throw new FrameException(e); } } /** * Sets the authentication method. * @param authMethods The value identifier of authentication method information element. * @throws FrameException */ public void setAuthMethods(int authMethods) throws FrameException { try { ByteBuffer byteBuffer = new ByteBuffer(ByteBuffer.SIZE_16BITS); byteBuffer.put16bits(authMethods); infoElements.put(InfoElement.AUTHMETHODS, byteBuffer.getBuffer()); } catch (Exception e) { throw new FrameException(e); } } /** * Gets the called number. * @return The called number in a String. * @throws FrameException */ public String getCalledNumber() throws FrameException { try { byte data[] = (byte[])infoElements.get(InfoElement.CALLED_NUMBER); return new String(data); } catch (Exception e) { throw new FrameException(e); } } /** * Sets the called number. * @param calledNumber The called number in a String. */ public void setCalledNumber(String calledNumber) { infoElements.put(InfoElement.CALLED_NUMBER, calledNumber.getBytes()); } /** * Gets the calling name. * @return The calling name in a String. * @throws FrameException */ public String getCallingName() throws FrameException { try { byte data[] = (byte[])infoElements.get(InfoElement.CALLING_NAME); return new String(data); } catch (Exception e) { throw new FrameException(e); } } /** * Sets the calling name. * @param callingNumber The calling name in a String. */ public void setCallingName(String callingName) { infoElements.put(InfoElement.CALLING_NAME, callingName.getBytes()); } /** * Gets the calling number. * @return The calling number in a String. * @throws FrameException */ public String getCallingNumber() throws FrameException { try { byte data[] = (byte[])infoElements.get(InfoElement.CALLING_NUMBER); return new String(data); } catch (Exception e) { throw new FrameException(e); } } /** * Sets the calling number. * @param callingNumber The calling number in a String. */ public void setCallingNumber(String callingNumber) { infoElements.put(InfoElement.CALLING_NUMBER, callingNumber.getBytes()); } /** Gets capabilities. * @return A long with capabilities. * @throws FrameException */ public long getCapability() throws FrameException { try { byte data[] = (byte[])infoElements.get(InfoElement.CAPABILITY); ByteBuffer byteBuffer = new ByteBuffer(data); return byteBuffer.get32bits(); } catch (Exception e) { throw new FrameException(e); } } /** * Sets capabilities. * @param capability A long with capabilities. * @throws FrameException */ public void setCapability(long capability) throws FrameException { try { ByteBuffer byteBuffer = new ByteBuffer(ByteBuffer.SIZE_32BITS); byteBuffer.put32bits(capability); infoElements.put(InfoElement.CAPABILITY, byteBuffer.getBuffer()); } catch (Exception e) { throw new FrameException(e); } } /** * Gets cause. * @return The string with the cause. * @throws FrameException */ public String getCause() throws FrameException { try { byte data[] = (byte[])infoElements.get(InfoElement.CAUSE); return new String(data); } catch (Exception e) { throw new FrameException(e); } } /** * Sets the cause information element. * @param cause The string with the cause. */ public void setCause(String cause) { infoElements.put(InfoElement.CAUSE, cause.getBytes()); } /** * Gets cause code. * @return The cause code as an integer. * @throws FrameException */ public int getCauseCode() throws FrameException { try { byte data[] = (byte[])infoElements.get(InfoElement.CAUSECODE); ByteBuffer byteBuffer = new ByteBuffer(data); return byteBuffer.get16bits(); } catch (Exception e) { throw new FrameException(e); } } /** * Sets the cause code. * @param causeCode The cause code as an integer. * @throws FrameException */ public void setCauseCode(int causeCode) throws FrameException { try { ByteBuffer byteBuffer = new ByteBuffer(ByteBuffer.SIZE_16BITS); byteBuffer.put16bits(causeCode); infoElements.put(InfoElement.CAUSECODE, byteBuffer.getBuffer()); } catch (Exception e) { throw new FrameException(e); } } /** * Gets challenge. * @return The challenge as string. * @throws FrameException */ public String getChallenge() throws FrameException { try { byte data[] = (byte[])infoElements.get(InfoElement.CHALLENGE); return new String(data); } catch (Exception e) { throw new FrameException(e); } } /** * Sets the challenge. * @param challenge The challenge as string. */ public void setChallenge(String challenge) { infoElements.put(InfoElement.CHALLENGE, challenge.getBytes()); } /** * Gets format. * @return The format as long. * @throws FrameException */ public long getFormat() throws FrameException { try { byte data[] = (byte[])infoElements.get(InfoElement.FORMAT); ByteBuffer byteBuffer = new ByteBuffer(data); return byteBuffer.get32bits(); } catch (Exception e) { throw new FrameException(e); } } /** * Sets format. * @param format The format as long. * @throws FrameException */ public void setFormat(long format) throws FrameException { try { ByteBuffer byteBuffer = new ByteBuffer(ByteBuffer.SIZE_32BITS); byteBuffer.put32bits(format); infoElements.put(InfoElement.FORMAT, byteBuffer.getBuffer()); } catch (Exception e) { throw new FrameException(e); } } /** * Gets MD5 result. * @return The MD5 result as string. * @throws FrameException */ public String getMD5Result() throws FrameException { try { byte data[] = (byte[])infoElements.get(InfoElement.MD5_RESULT); return new String(data); } catch (Exception e) { throw new FrameException(e); } } /** * Sets the MD5 result. * @param md5 The MD5 result as string. * @throws FrameException */ public void setMD5Result(String md5) throws FrameException { infoElements.put(InfoElement.MD5_RESULT, md5.getBytes()); } /** * Sets the music on hold * @throws FrameException */ public void setMusicOnHold() throws FrameException { infoElements.put(InfoElement.MUSICONHOLD, new byte[0]); } /** * Gets the register refresh * @return The register refresh as an intenger. * @throws FrameException */ public int getRefresh() throws FrameException { try { byte data[] = (byte[])infoElements.get(InfoElement.REFRESH); ByteBuffer byteBuffer = new ByteBuffer(data); return byteBuffer.get16bits(); } catch (Exception e) { throw new FrameException(e); } } /** * Sets the register refresh * @param refresh The register refresh as an integer. * @throws FrameException */ public void setRefresh(int refresh) throws FrameException { try { ByteBuffer byteBuffer = new ByteBuffer(ByteBuffer.SIZE_16BITS); byteBuffer.put16bits(refresh); infoElements.put(InfoElement.REFRESH, byteBuffer.getBuffer()); } catch (Exception e) { throw new FrameException(e); } } /** * Gets an unknown subclass * @return the cause code as an integer. * @throws FrameException */ public int getUnknown() throws FrameException { try { byte data[] = (byte[])infoElements.get(InfoElement.UNKNOWN); ByteBuffer byteBuffer = new ByteBuffer(data); return byteBuffer.get16bits(); } catch (Exception e) { throw new FrameException(e); } } /** * Sets an unknown subclass * @param subclass the unknown subclass as an integer. * @throws FrameException */ public void setUnknown(int subclass) throws FrameException { try { ByteBuffer byteBuffer = new ByteBuffer(ByteBuffer.SIZE_8BITS); byteBuffer.put8bits(subclass); infoElements.put(InfoElement.UNKNOWN, byteBuffer.getBuffer()); } catch (Exception e) { throw new FrameException(e); } } /** * Gets the user name. * @return The user name as string. * @throws FrameException */ public String getUserName() throws FrameException { try { byte data[] = (byte[])infoElements.get(InfoElement.USERNAME); return new String(data); } catch (Exception e) { throw new FrameException(e); } } /** * Sets the user name. * @param userName The user name as string. */ public void setUserName(String userName) { infoElements.put(InfoElement.USERNAME, userName.getBytes()); } /** * Gets the version. * @return The version as integer. * @throws FrameException */ public int getVersion() throws FrameException { try { byte data[] = (byte[])infoElements.get(InfoElement.VERSION); ByteBuffer byteBuffer = new ByteBuffer(data); return byteBuffer.get16bits(); } catch (Exception e) { throw new FrameException(e); } } /** * Sets the version * @param version The version as integer. * @throws FrameException */ public void setVersion(int version) throws FrameException { try { ByteBuffer byteBuffer = new ByteBuffer(ByteBuffer.SIZE_16BITS); byteBuffer.put16bits(version); infoElements.put(InfoElement.VERSION, byteBuffer.getBuffer()); } catch (Exception e) { throw new FrameException(e); } } public byte[] serialize() { try { byte[] superInBytes = super.serialize(); int iesBufferMaxSize = infoElements.size()*InfoElement.HEADER_LENGTH*InfoElement.MAX_DATA_LENGTH; byte[] iesBuffer = new byte[iesBufferMaxSize]; Enumeration keys = infoElements.keys(); int iesBufferSize = 0; for (;keys.hasMoreElements();) { Integer id = (Integer)keys.nextElement(); byte[] data = (byte[])infoElements.get(id); int ieLength = InfoElement.HEADER_LENGTH+data.length; ByteBuffer byteBuffer = new ByteBuffer(ieLength); byteBuffer.put8bits(id.byteValue()); byteBuffer.put8bits(data.length); byteBuffer.putByteArray(data); System.arraycopy(byteBuffer.getBuffer(), 0, iesBuffer, iesBufferSize, ieLength); iesBufferSize += ieLength; } byte[] result = new byte[superInBytes.length+iesBufferSize]; System.arraycopy(superInBytes, 0, result, 0, superInBytes.length); System.arraycopy(iesBuffer, 0, result, superInBytes.length, iesBufferSize); return result; } catch (Exception e) { return null; } } }