All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.pkts.packet.sip.impl.SipInitialLine Maven / Gradle / Ivy

/**
 * 
 */
package io.pkts.packet.sip.impl;

import io.pkts.buffer.Buffer;
import io.pkts.buffer.ByteNotFoundException;
import io.pkts.packet.sip.SipMessage;
import io.pkts.packet.sip.SipParseException;

import java.io.IOException;

/**
 * @author [email protected]
 */
public abstract class SipInitialLine extends SipParser {

    protected SipInitialLine() {
        // left empty intentionally
    }

    /**
     * Two initial lines are considered equal if:
     * 
    *
  • They are both a request or response line
  • *
  • If response, their status codes are the same (the human readable * reason is ignored)
  • *
  • If request, the request-uri must be equal according to the rules * of URI equality
  • *
* @param other * @return */ public abstract boolean equals(final Object other); /** * The request initial line as a raw buffer. * * @return */ public abstract Buffer getBuffer(); /** * Simple method to check whether the supplied buffer could be a SIP * response line. Hence, does it start with SIP/2.0 or not. Note, if this * method returns false it does not necessarily mean that this is a request * line but if you have already determined that that the incoming data could * be a SIP message (e.g. by using the method * {@link SipFramer#couldBeSipMessage(Buffer)}) then it is very likely that * it is a request line. * * @return * @throws IOException * @throws IndexOutOfBoundsException */ public static boolean isResponseLine(final Buffer buffer) throws IOException { if (buffer == null || buffer.getReadableBytes() < 7) { return false; } final byte a = buffer.getByte(0); final byte b = buffer.getByte(1); final byte c = buffer.getByte(2); final byte d = buffer.getByte(3); final byte e = buffer.getByte(4); final byte f = buffer.getByte(5); final byte g = buffer.getByte(6); return a == 'S' && b == 'I' && c == 'P' && d == '/' && e == '2' && f == '.' && g == '0'; } /** * Parse the buffer into a SIP initial line, which either can be a * {@link SipRequestLine} or a {@link SipResponseLine}. * * The parsing will only check so that a few things are correct but in * general it doesn't do any deeper analysis of the initial line. To make * sure that the resulting sip message actually is correct, call the * {@link SipMessage#verify()} method, which will do a deeper analysis of * the sip message * * @param buffer * @return */ public static final SipInitialLine parse(final Buffer buffer) throws SipParseException { Buffer part1 = null; Buffer part2 = null; Buffer part3 = null; try { part1 = buffer.readUntil(SipParser.SP); part2 = buffer.readUntil(SipParser.SP); part3 = buffer.readLine(); if (SipParser.SIP2_0.equals(part1)) { final int statusCode = part2.parseToInt(); return new SipResponseLine(statusCode, part3); } // not a response so then the last part must be the SIP/2.0 // otherwise this is not a valid SIP initial line expectSIP2_0(part3); return new SipRequestLine(part1, part2); } catch (final NumberFormatException e) { final int index = buffer.getReaderIndex() - part3.capacity() - part2.capacity() - 1; throw new SipParseException(index, "unable to parse the SIP response code as an integer"); } catch (final ByteNotFoundException e) { throw new SipParseException(buffer.getReaderIndex(), "expected space"); } catch (final SipParseException e) { // is only thrown by the expectSIP2_0. Calculate the correct // index into the buffer e.printStackTrace();; final int index = buffer.getReaderIndex() - part3.capacity() + e.getErrorOffset() - 1; throw new SipParseException(index, "Wrong SIP version"); } catch (final IOException e) { throw new SipParseException(buffer.getReaderIndex(), "could not read from stream", e); } } public static final SipInitialLine parse(final Buffer part1, final Buffer part2, final Buffer part3) throws SipParseException { try { if (SipParser.SIP2_0.equals(part1)) { final int statusCode = part2.parseToInt(); return new SipResponseLine(statusCode, part3); } // not a response so then the last part must be the SIP/2.0 // otherwise this is not a valid SIP initial line expectSIP2_0(part3); return new SipRequestLine(part1, part2); } catch (final NumberFormatException e) { throw new SipParseException(part1.capacity() + 1, "unable to parse the SIP response code as an integer"); } catch (final SipParseException e) { // is only thrown by the expectSIP2_0. Calculate the correct // index into the buffer throw new SipParseException(part1.capacity() + 1 + part2.capacity() + 1, "Wrong SIP version"); } catch (final IOException e) { throw new SipParseException(0, "could not read from stream", e); } } public SipRequestLine toRequestLine() { throw new ClassCastException("Cannot cast object to " + SipRequestLine.class); } public SipResponseLine toResponseLine() { throw new ClassCastException("Cannot cast object to " + SipResponseLine.class); } public boolean isResponseLine() { return false; } public boolean isRequestLine() { return false; } /** * Write the bytes representing this {@link SipInitialLine} into the * destination {@link Buffer}. * * @param dst */ public abstract void getBytes(Buffer dst); @Override protected abstract SipInitialLine clone(); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy